aboutsummaryrefslogtreecommitdiffstats
path: root/vendor/github.com/ebfe/scard/scard_unix.go
diff options
context:
space:
mode:
Diffstat (limited to 'vendor/github.com/ebfe/scard/scard_unix.go')
-rw-r--r--vendor/github.com/ebfe/scard/scard_unix.go206
1 files changed, 206 insertions, 0 deletions
diff --git a/vendor/github.com/ebfe/scard/scard_unix.go b/vendor/github.com/ebfe/scard/scard_unix.go
new file mode 100644
index 000000000..21910318f
--- /dev/null
+++ b/vendor/github.com/ebfe/scard/scard_unix.go
@@ -0,0 +1,206 @@
+// +build !windows,!darwin
+
+package scard
+
+// #cgo pkg-config: libpcsclite
+// #include <stdlib.h>
+// #include <winscard.h>
+import "C"
+
+import (
+ "unsafe"
+)
+
+func (e Error) Error() string {
+ return "scard: " + C.GoString(C.pcsc_stringify_error(C.LONG(e)))
+}
+
+// Version returns the libpcsclite version string
+func Version() string {
+ return C.PCSCLITE_VERSION_NUMBER
+}
+
+func scardEstablishContext(scope Scope, reserved1, reserved2 uintptr) (uintptr, Error) {
+ var ctx C.SCARDCONTEXT
+ r := C.SCardEstablishContext(C.DWORD(scope), C.LPCVOID(reserved1), C.LPCVOID(reserved2), &ctx)
+ return uintptr(ctx), Error(r)
+}
+
+func scardIsValidContext(ctx uintptr) Error {
+ r := C.SCardIsValidContext(C.SCARDCONTEXT(ctx))
+ return Error(r)
+}
+
+func scardCancel(ctx uintptr) Error {
+ r := C.SCardCancel(C.SCARDCONTEXT(ctx))
+ return Error(r)
+}
+
+func scardReleaseContext(ctx uintptr) Error {
+ r := C.SCardReleaseContext(C.SCARDCONTEXT(ctx))
+ return Error(r)
+}
+
+func scardListReaders(ctx uintptr, groups, buf unsafe.Pointer, bufLen uint32) (uint32, Error) {
+ dwBufLen := C.DWORD(bufLen)
+ r := C.SCardListReaders(C.SCARDCONTEXT(ctx), (C.LPCSTR)(groups), (C.LPSTR)(buf), &dwBufLen)
+ return uint32(dwBufLen), Error(r)
+}
+
+func scardListReaderGroups(ctx uintptr, buf unsafe.Pointer, bufLen uint32) (uint32, Error) {
+ dwBufLen := C.DWORD(bufLen)
+ r := C.SCardListReaderGroups(C.SCARDCONTEXT(ctx), (C.LPSTR)(buf), &dwBufLen)
+ return uint32(dwBufLen), Error(r)
+}
+
+func scardGetStatusChange(ctx uintptr, timeout uint32, states []scardReaderState) Error {
+ r := C.SCardGetStatusChange(C.SCARDCONTEXT(ctx), C.DWORD(timeout), (C.LPSCARD_READERSTATE)(unsafe.Pointer(&states[0])), C.DWORD(len(states)))
+ return Error(r)
+}
+
+func scardConnect(ctx uintptr, reader unsafe.Pointer, shareMode ShareMode, proto Protocol) (uintptr, Protocol, Error) {
+ var handle C.SCARDHANDLE
+ var activeProto C.DWORD
+
+ r := C.SCardConnect(C.SCARDCONTEXT(ctx), C.LPCSTR(reader), C.DWORD(shareMode), C.DWORD(proto), &handle, &activeProto)
+
+ return uintptr(handle), Protocol(activeProto), Error(r)
+}
+
+func scardDisconnect(card uintptr, d Disposition) Error {
+ r := C.SCardDisconnect(C.SCARDHANDLE(card), C.DWORD(d))
+ return Error(r)
+}
+
+func scardReconnect(card uintptr, mode ShareMode, proto Protocol, disp Disposition) (Protocol, Error) {
+ var activeProtocol C.DWORD
+ r := C.SCardReconnect(C.SCARDHANDLE(card), C.DWORD(mode), C.DWORD(proto), C.DWORD(disp), &activeProtocol)
+ return Protocol(activeProtocol), Error(r)
+}
+
+func scardBeginTransaction(card uintptr) Error {
+ r := C.SCardBeginTransaction(C.SCARDHANDLE(card))
+ return Error(r)
+}
+
+func scardEndTransaction(card uintptr, disp Disposition) Error {
+ r := C.SCardEndTransaction(C.SCARDHANDLE(card), C.DWORD(disp))
+ return Error(r)
+}
+
+func scardCardStatus(card uintptr) (string, State, Protocol, []byte, Error) {
+ var readerBuf [C.MAX_READERNAME + 1]byte
+ var readerLen = C.DWORD(len(readerBuf))
+ var state, proto C.DWORD
+ var atr [maxAtrSize]byte
+ var atrLen = C.DWORD(len(atr))
+
+ r := C.SCardStatus(C.SCARDHANDLE(card), (C.LPSTR)(unsafe.Pointer(&readerBuf[0])), &readerLen, &state, &proto, (*C.BYTE)(&atr[0]), &atrLen)
+
+ return decodestr(readerBuf[:readerLen]), State(state), Protocol(proto), atr[:atrLen], Error(r)
+}
+
+func scardTransmit(card uintptr, proto Protocol, cmd []byte, rsp []byte) (uint32, Error) {
+ var sendpci C.SCARD_IO_REQUEST
+ var recvpci C.SCARD_IO_REQUEST
+ var rspLen = C.DWORD(len(rsp))
+
+ switch proto {
+ case ProtocolT0, ProtocolT1:
+ sendpci.dwProtocol = C.ulong(proto)
+ default:
+ panic("unknown protocol")
+ }
+ sendpci.cbPciLength = C.sizeof_SCARD_IO_REQUEST
+
+ r := C.SCardTransmit(C.SCARDHANDLE(card), &sendpci, (*C.BYTE)(&cmd[0]), C.DWORD(len(cmd)), &recvpci, (*C.BYTE)(&rsp[0]), &rspLen)
+
+ return uint32(rspLen), Error(r)
+}
+
+func scardControl(card uintptr, ioctl uint32, in, out []byte) (uint32, Error) {
+ var ptrIn C.LPCVOID
+ var outLen = C.DWORD(len(out))
+
+ if len(in) != 0 {
+ ptrIn = C.LPCVOID(unsafe.Pointer(&in[0]))
+ }
+
+ r := C.SCardControl(C.SCARDHANDLE(card), C.DWORD(ioctl), ptrIn, C.DWORD(len(in)), (C.LPVOID)(unsafe.Pointer(&out[0])), C.DWORD(len(out)), &outLen)
+ return uint32(outLen), Error(r)
+}
+
+func scardGetAttrib(card uintptr, id Attrib, buf []byte) (uint32, Error) {
+ var ptr C.LPBYTE
+
+ if len(buf) != 0 {
+ ptr = C.LPBYTE(unsafe.Pointer(&buf[0]))
+ }
+
+ bufLen := C.DWORD(len(buf))
+ r := C.SCardGetAttrib(C.SCARDHANDLE(card), C.DWORD(id), ptr, &bufLen)
+
+ return uint32(bufLen), Error(r)
+}
+
+func scardSetAttrib(card uintptr, id Attrib, buf []byte) Error {
+ r := C.SCardSetAttrib(C.SCARDHANDLE(card), C.DWORD(id), (*C.BYTE)(unsafe.Pointer(&buf[0])), C.DWORD(len(buf)))
+ return Error(r)
+}
+
+type strbuf []byte
+
+func encodestr(s string) (strbuf, error) {
+ buf := strbuf(s + "\x00")
+ return buf, nil
+}
+
+func decodestr(buf strbuf) string {
+ if len(buf) == 0 {
+ return ""
+ }
+
+ if buf[len(buf)-1] == 0 {
+ buf = buf[:len(buf)-1]
+ }
+
+ return string(buf)
+}
+
+type scardReaderState struct {
+ szReader uintptr
+ pvUserData uintptr
+ dwCurrentState uintptr
+ dwEventState uintptr
+ cbAtr uintptr
+ rgbAtr [33]byte
+}
+
+var pinned = map[string]*strbuf{}
+
+func (rs *ReaderState) toSys() (scardReaderState, error) {
+ var sys scardReaderState
+
+ creader, err := encodestr(rs.Reader)
+ if err != nil {
+ return scardReaderState{}, err
+ }
+ pinned[rs.Reader] = &creader
+ sys.szReader = uintptr(creader.ptr())
+ sys.dwCurrentState = uintptr(rs.CurrentState)
+ sys.cbAtr = uintptr(len(rs.Atr))
+ for i, v := range rs.Atr {
+ sys.rgbAtr[i] = byte(v)
+ }
+ return sys, nil
+}
+
+func (rs *ReaderState) update(sys *scardReaderState) {
+ rs.EventState = StateFlag(sys.dwEventState)
+ if sys.cbAtr > 0 {
+ rs.Atr = make([]byte, int(sys.cbAtr))
+ for i := 0; i < int(sys.cbAtr); i++ {
+ rs.Atr[i] = byte(sys.rgbAtr[i])
+ }
+ }
+}