diff options
Diffstat (limited to 'vendor/github.com/ebfe')
-rw-r--r-- | vendor/github.com/ebfe/scard/LICENSE | 23 | ||||
-rw-r--r-- | vendor/github.com/ebfe/scard/README.md | 14 | ||||
-rw-r--r-- | vendor/github.com/ebfe/scard/scard.go | 283 | ||||
-rw-r--r-- | vendor/github.com/ebfe/scard/scard_darwin.go | 219 | ||||
-rw-r--r-- | vendor/github.com/ebfe/scard/scard_unix.go | 206 | ||||
-rw-r--r-- | vendor/github.com/ebfe/scard/scard_windows.go | 221 | ||||
-rw-r--r-- | vendor/github.com/ebfe/scard/zconst.go | 190 |
7 files changed, 1156 insertions, 0 deletions
diff --git a/vendor/github.com/ebfe/scard/LICENSE b/vendor/github.com/ebfe/scard/LICENSE new file mode 100644 index 000000000..0d220e7ae --- /dev/null +++ b/vendor/github.com/ebfe/scard/LICENSE @@ -0,0 +1,23 @@ +Copyright (c) 2016, Michael Gehring <mg@ebfe.org> +All rights reserved. + +Redistribution and use in source and binary forms, with or without modification, +are permitted provided that the following conditions are met: + +* Redistributions of source code must retain the above copyright notice, this + list of conditions and the following disclaimer. + +* Redistributions in binary form must reproduce the above copyright notice, this + list of conditions and the following disclaimer in the documentation and/or + other materials provided with the distribution. + +THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND +ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED +WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE +DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR +ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES +(INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; +LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON +ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT +(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS +SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. diff --git a/vendor/github.com/ebfe/scard/README.md b/vendor/github.com/ebfe/scard/README.md new file mode 100644 index 000000000..cdafb2c7b --- /dev/null +++ b/vendor/github.com/ebfe/scard/README.md @@ -0,0 +1,14 @@ +scard +===== + +[![GoDoc](https://godoc.org/github.com/ebfe/scard?status.svg)](https://godoc.org/github.com/ebfe/scard) + +Go bindings to the PC/SC API. + +## Installation + + go get github.com/ebfe/scard + +## Bugs + + - Memory layouts/GC needs a thorough review. diff --git a/vendor/github.com/ebfe/scard/scard.go b/vendor/github.com/ebfe/scard/scard.go new file mode 100644 index 000000000..a5f0ae16b --- /dev/null +++ b/vendor/github.com/ebfe/scard/scard.go @@ -0,0 +1,283 @@ +// Package scard provides bindings to the PC/SC API. +package scard + +import ( + "time" + "unsafe" +) + +type CardStatus struct { + Reader string + State State + ActiveProtocol Protocol + Atr []byte +} + +type ReaderState struct { + Reader string + UserData interface{} + CurrentState StateFlag + EventState StateFlag + Atr []byte +} + +type Context struct { + ctx uintptr +} + +type Card struct { + handle uintptr + activeProtocol Protocol +} + +// wraps SCardEstablishContext +func EstablishContext() (*Context, error) { + ctx, r := scardEstablishContext(ScopeSystem, 0, 0) + if r != ErrSuccess { + return nil, r + } + + return &Context{ctx: ctx}, nil +} + +// wraps SCardIsValidContext +func (ctx *Context) IsValid() (bool, error) { + r := scardIsValidContext(ctx.ctx) + switch r { + case ErrSuccess: + return true, nil + case ErrInvalidHandle: + return false, nil + default: + return false, r + } +} + +// wraps SCardCancel +func (ctx *Context) Cancel() error { + r := scardCancel(ctx.ctx) + if r != ErrSuccess { + return r + } + return nil +} + +// wraps SCardReleaseContext +func (ctx *Context) Release() error { + r := scardReleaseContext(ctx.ctx) + if r != ErrSuccess { + return r + } + return nil +} + +// wraps SCardListReaders +func (ctx *Context) ListReaders() ([]string, error) { + needed, r := scardListReaders(ctx.ctx, nil, nil, 0) + if r != ErrSuccess { + return nil, r + } + + buf := make(strbuf, needed) + n, r := scardListReaders(ctx.ctx, nil, buf.ptr(), uint32(len(buf))) + if r != ErrSuccess { + return nil, r + } + return decodemstr(buf[:n]), nil +} + +// wraps SCardListReaderGroups +func (ctx *Context) ListReaderGroups() ([]string, error) { + needed, r := scardListReaderGroups(ctx.ctx, nil, 0) + if r != ErrSuccess { + return nil, r + } + + buf := make(strbuf, needed) + n, r := scardListReaderGroups(ctx.ctx, buf.ptr(), uint32(len(buf))) + if r != ErrSuccess { + return nil, r + } + return decodemstr(buf[:n]), nil +} + +// wraps SCardGetStatusChange +func (ctx *Context) GetStatusChange(readerStates []ReaderState, timeout time.Duration) error { + + dwTimeout := durationToTimeout(timeout) + states := make([]scardReaderState, len(readerStates)) + + for i := range readerStates { + var err error + states[i], err = readerStates[i].toSys() + if err != nil { + return err + } + } + + r := scardGetStatusChange(ctx.ctx, dwTimeout, states) + if r != ErrSuccess { + return r + } + + for i := range readerStates { + (&readerStates[i]).update(&states[i]) + } + + return nil +} + +// wraps SCardConnect +func (ctx *Context) Connect(reader string, mode ShareMode, proto Protocol) (*Card, error) { + creader, err := encodestr(reader) + if err != nil { + return nil, err + } + handle, activeProtocol, r := scardConnect(ctx.ctx, creader.ptr(), mode, proto) + if r != ErrSuccess { + return nil, r + } + return &Card{handle: handle, activeProtocol: activeProtocol}, nil +} + +// wraps SCardDisconnect +func (card *Card) Disconnect(d Disposition) error { + r := scardDisconnect(card.handle, d) + if r != ErrSuccess { + return r + } + return nil +} + +// wraps SCardReconnect +func (card *Card) Reconnect(mode ShareMode, proto Protocol, disp Disposition) error { + activeProtocol, r := scardReconnect(card.handle, mode, proto, disp) + if r != ErrSuccess { + return r + } + card.activeProtocol = activeProtocol + return nil +} + +// wraps SCardBeginTransaction +func (card *Card) BeginTransaction() error { + r := scardBeginTransaction(card.handle) + if r != ErrSuccess { + return r + } + return nil +} + +// wraps SCardEndTransaction +func (card *Card) EndTransaction(disp Disposition) error { + r := scardEndTransaction(card.handle, disp) + if r != ErrSuccess { + return r + } + return nil +} + +// wraps SCardStatus +func (card *Card) Status() (*CardStatus, error) { + reader, state, proto, atr, err := scardCardStatus(card.handle) + if err != ErrSuccess { + return nil, err + } + return &CardStatus{Reader: reader, State: state, ActiveProtocol: proto, Atr: atr}, nil +} + +// wraps SCardTransmit +func (card *Card) Transmit(cmd []byte) ([]byte, error) { + rsp := make([]byte, maxBufferSizeExtended) + rspLen, err := scardTransmit(card.handle, card.activeProtocol, cmd, rsp) + if err != ErrSuccess { + return nil, err + } + return rsp[:rspLen], nil +} + +// wraps SCardControl +func (card *Card) Control(ioctl uint32, in []byte) ([]byte, error) { + var out [0xffff]byte + outLen, err := scardControl(card.handle, ioctl, in, out[:]) + if err != ErrSuccess { + return nil, err + } + return out[:outLen], nil +} + +// wraps SCardGetAttrib +func (card *Card) GetAttrib(id Attrib) ([]byte, error) { + needed, err := scardGetAttrib(card.handle, id, nil) + if err != ErrSuccess { + return nil, err + } + + var attrib = make([]byte, needed) + n, err := scardGetAttrib(card.handle, id, attrib) + if err != ErrSuccess { + return nil, err + } + return attrib[:n], nil +} + +// wraps SCardSetAttrib +func (card *Card) SetAttrib(id Attrib, data []byte) error { + err := scardSetAttrib(card.handle, id, data) + if err != ErrSuccess { + return err + } + return nil +} + +func durationToTimeout(timeout time.Duration) uint32 { + switch { + case timeout < 0: + return infiniteTimeout + case timeout > time.Duration(infiniteTimeout)*time.Millisecond: + return infiniteTimeout - 1 + default: + return uint32(timeout / time.Millisecond) + } +} + +func (buf strbuf) ptr() unsafe.Pointer { + return unsafe.Pointer(&buf[0]) +} + +func (buf strbuf) split() []strbuf { + var chunks []strbuf + for len(buf) > 0 && buf[0] != 0 { + i := 0 + for i = range buf { + if buf[i] == 0 { + break + } + } + chunks = append(chunks, buf[:i+1]) + buf = buf[i+1:] + } + + return chunks +} + +func encodemstr(strings ...string) (strbuf, error) { + var buf strbuf + for _, s := range strings { + utf16, err := encodestr(s) + if err != nil { + return nil, err + } + buf = append(buf, utf16...) + } + buf = append(buf, 0) + return buf, nil +} + +func decodemstr(buf strbuf) []string { + var strings []string + for _, chunk := range buf.split() { + strings = append(strings, decodestr(chunk)) + } + return strings +} diff --git a/vendor/github.com/ebfe/scard/scard_darwin.go b/vendor/github.com/ebfe/scard/scard_darwin.go new file mode 100644 index 000000000..83a1597b3 --- /dev/null +++ b/vendor/github.com/ebfe/scard/scard_darwin.go @@ -0,0 +1,219 @@ +// +build darwin + +package scard + +// #cgo LDFLAGS: -framework PCSC +// #cgo CFLAGS: -I /usr/include +// #include <stdlib.h> +// #include <PCSC/winscard.h> +// #include <PCSC/wintypes.h> +import "C" + +import ( + "unsafe" +) + +func (e Error) Error() string { + return "scard: " + C.GoString(C.pcsc_stringify_error(C.int32_t(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.uint32_t(scope), unsafe.Pointer(reserved1), unsafe.Pointer(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.uint32_t(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.uint32_t(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 { + // In darwin, the LPSCARD_READERSTATE_A has 1 byte alignment and hence + // has no trailing padding. Go does add 3 bytes of padding (on both 32 + // and 64 bits), so we pack an array manually instead. + const size = int(unsafe.Sizeof(states[0])) - 3 + buf := make([]byte, size*len(states)) + for i, _ := range states { + copy(buf[i*size:(i+1)*size], (*(*[size]byte)(unsafe.Pointer(&states[i])))[:]) + } + r := C.SCardGetStatusChange(C.SCARDCONTEXT(ctx), C.uint32_t(timeout), (C.LPSCARD_READERSTATE_A)(unsafe.Pointer(&buf[0])), C.uint32_t(len(states))) + for i, _ := range states { + copy((*(*[size]byte)(unsafe.Pointer(&states[i])))[:], buf[i*size:(i+1)*size]) + } + return Error(r) +} + +func scardConnect(ctx uintptr, reader unsafe.Pointer, shareMode ShareMode, proto Protocol) (uintptr, Protocol, Error) { + var handle C.SCARDHANDLE + var activeProto C.uint32_t + + r := C.SCardConnect(C.SCARDCONTEXT(ctx), C.LPCSTR(reader), C.uint32_t(shareMode), C.uint32_t(proto), &handle, &activeProto) + + return uintptr(handle), Protocol(activeProto), Error(r) +} + +func scardDisconnect(card uintptr, d Disposition) Error { + r := C.SCardDisconnect(C.SCARDHANDLE(card), C.uint32_t(d)) + return Error(r) +} + +func scardReconnect(card uintptr, mode ShareMode, proto Protocol, disp Disposition) (Protocol, Error) { + var activeProtocol C.uint32_t + r := C.SCardReconnect(C.SCARDHANDLE(card), C.uint32_t(mode), C.uint32_t(proto), C.uint32_t(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.uint32_t(disp)) + return Error(r) +} + +func scardCardStatus(card uintptr) (string, State, Protocol, []byte, Error) { + var readerBuf [C.MAX_READERNAME + 1]byte + var readerLen = C.uint32_t(len(readerBuf)) + var state, proto C.uint32_t + var atr [maxAtrSize]byte + var atrLen = C.uint32_t(len(atr)) + + r := C.SCardStatus(C.SCARDHANDLE(card), (C.LPSTR)(unsafe.Pointer(&readerBuf[0])), &readerLen, &state, &proto, (*C.uchar)(&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.uint32_t(len(rsp)) + + switch proto { + case ProtocolT0, ProtocolT1: + sendpci.dwProtocol = C.uint32_t(proto) + default: + panic("unknown protocol") + } + sendpci.cbPciLength = C.sizeof_SCARD_IO_REQUEST + + r := C.SCardTransmit(C.SCARDHANDLE(card), &sendpci, (*C.uchar)(&cmd[0]), C.uint32_t(len(cmd)), &recvpci, (*C.uchar)(&rsp[0]), &rspLen) + + return uint32(rspLen), Error(r) +} + +func scardControl(card uintptr, ioctl uint32, in, out []byte) (uint32, Error) { + var ptrIn unsafe.Pointer + var outLen = C.uint32_t(len(out)) + + if len(in) != 0 { + ptrIn = unsafe.Pointer(&in[0]) + } + + r := C.SCardControl(C.SCARDHANDLE(card), C.uint32_t(ioctl), ptrIn, C.uint32_t(len(in)), unsafe.Pointer(&out[0]), C.uint32_t(len(out)), &outLen) + return uint32(outLen), Error(r) +} + +func scardGetAttrib(card uintptr, id Attrib, buf []byte) (uint32, Error) { + var ptr *C.uint8_t + + if len(buf) != 0 { + ptr = (*C.uint8_t)(&buf[0]) + } + + bufLen := C.uint32_t(len(buf)) + r := C.SCardGetAttrib(C.SCARDHANDLE(card), C.uint32_t(id), ptr, &bufLen) + + return uint32(bufLen), Error(r) +} + +func scardSetAttrib(card uintptr, id Attrib, buf []byte) Error { + r := C.SCardSetAttrib(C.SCARDHANDLE(card), C.uint32_t(id), ((*C.uint8_t)(&buf[0])), C.uint32_t(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 uint32 + dwEventState uint32 + cbAtr uint32 + 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 = uint32(rs.CurrentState) + sys.cbAtr = uint32(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]) + } + } +} 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]) + } + } +} diff --git a/vendor/github.com/ebfe/scard/scard_windows.go b/vendor/github.com/ebfe/scard/scard_windows.go new file mode 100644 index 000000000..bc852da04 --- /dev/null +++ b/vendor/github.com/ebfe/scard/scard_windows.go @@ -0,0 +1,221 @@ +package scard + +import ( + "fmt" + "syscall" + "unsafe" +) + +var ( + modwinscard = syscall.NewLazyDLL("winscard.dll") + + procEstablishContext = modwinscard.NewProc("SCardEstablishContext") + procReleaseContext = modwinscard.NewProc("SCardReleaseContext") + procIsValidContext = modwinscard.NewProc("SCardIsValidContext") + procCancel = modwinscard.NewProc("SCardCancel") + procListReaders = modwinscard.NewProc("SCardListReadersW") + procListReaderGroups = modwinscard.NewProc("SCardListReaderGroupsW") + procGetStatusChange = modwinscard.NewProc("SCardGetStatusChangeW") + procConnect = modwinscard.NewProc("SCardConnectW") + procDisconnect = modwinscard.NewProc("SCardDisconnect") + procReconnect = modwinscard.NewProc("SCardReconnect") + procBeginTransaction = modwinscard.NewProc("SCardBeginTransaction") + procEndTransaction = modwinscard.NewProc("SCardEndTransaction") + procStatus = modwinscard.NewProc("SCardStatusW") + procTransmit = modwinscard.NewProc("SCardTransmit") + procControl = modwinscard.NewProc("SCardControl") + procGetAttrib = modwinscard.NewProc("SCardGetAttrib") + procSetAttrib = modwinscard.NewProc("SCardSetAttrib") + + dataT0Pci = modwinscard.NewProc("g_rgSCardT0Pci") + dataT1Pci = modwinscard.NewProc("g_rgSCardT1Pci") +) + +var scardIoReqT0 uintptr +var scardIoReqT1 uintptr + +func init() { + if err := dataT0Pci.Find(); err != nil { + panic(err) + } + scardIoReqT0 = dataT0Pci.Addr() + if err := dataT1Pci.Find(); err != nil { + panic(err) + } + scardIoReqT1 = dataT1Pci.Addr() +} + +func (e Error) Error() string { + err := syscall.Errno(e) + return fmt.Sprintf("scard: error(%x): %s", uintptr(e), err.Error()) +} + +func scardEstablishContext(scope Scope, reserved1, reserved2 uintptr) (uintptr, Error) { + var ctx uintptr + r, _, _ := procEstablishContext.Call(uintptr(scope), reserved1, reserved2, uintptr(unsafe.Pointer(&ctx))) + return ctx, Error(r) +} + +func scardIsValidContext(ctx uintptr) Error { + r, _, _ := procIsValidContext.Call(ctx) + return Error(r) +} + +func scardCancel(ctx uintptr) Error { + r, _, _ := procCancel.Call(ctx) + return Error(r) +} + +func scardReleaseContext(ctx uintptr) Error { + r, _, _ := procReleaseContext.Call(ctx) + return Error(r) +} + +func scardListReaders(ctx uintptr, groups, buf unsafe.Pointer, bufLen uint32) (uint32, Error) { + dwBufLen := uint32(bufLen) + r, _, _ := procListReaders.Call(ctx, uintptr(groups), uintptr(buf), uintptr(unsafe.Pointer(&dwBufLen))) + return dwBufLen, Error(r) +} + +func scardListReaderGroups(ctx uintptr, buf unsafe.Pointer, bufLen uint32) (uint32, Error) { + dwBufLen := uint32(bufLen) + r, _, _ := procListReaderGroups.Call(ctx, uintptr(buf), uintptr(unsafe.Pointer(&dwBufLen))) + return dwBufLen, Error(r) +} + +func scardGetStatusChange(ctx uintptr, timeout uint32, states []scardReaderState) Error { + r, _, _ := procGetStatusChange.Call(ctx, uintptr(timeout), uintptr(unsafe.Pointer(&states[0])), uintptr(len(states))) + return Error(r) +} + +func scardConnect(ctx uintptr, reader unsafe.Pointer, shareMode ShareMode, proto Protocol) (uintptr, Protocol, Error) { + var handle uintptr + var activeProto uint32 + + r, _, _ := procConnect.Call(ctx, uintptr(reader), uintptr(shareMode), uintptr(proto), uintptr(unsafe.Pointer(&handle)), uintptr(unsafe.Pointer(&activeProto))) + + return handle, Protocol(activeProto), Error(r) +} + +func scardDisconnect(card uintptr, d Disposition) Error { + r, _, _ := procDisconnect.Call(card, uintptr(d)) + return Error(r) +} + +func scardReconnect(card uintptr, mode ShareMode, proto Protocol, disp Disposition) (Protocol, Error) { + var activeProtocol uint32 + r, _, _ := procReconnect.Call(card, uintptr(mode), uintptr(proto), uintptr(disp), uintptr(unsafe.Pointer(&activeProtocol))) + return Protocol(activeProtocol), Error(r) +} + +func scardBeginTransaction(card uintptr) Error { + r, _, _ := procBeginTransaction.Call(card) + return Error(r) +} + +func scardEndTransaction(card uintptr, disp Disposition) Error { + r, _, _ := procEndTransaction.Call(card, uintptr(disp)) + return Error(r) +} + +func scardCardStatus(card uintptr) (string, State, Protocol, []byte, Error) { + var state, proto uint32 + var atr [maxAtrSize]byte + var atrLen = uint32(len(atr)) + + reader := make(strbuf, maxReadername+1) + readerLen := uint32(len(reader)) + + r, _, _ := procStatus.Call(card, uintptr(reader.ptr()), uintptr(unsafe.Pointer(&readerLen)), uintptr(unsafe.Pointer(&state)), uintptr(unsafe.Pointer(&proto)), uintptr(unsafe.Pointer(&atr[0])), uintptr(unsafe.Pointer(&atrLen))) + + return decodestr(reader[:readerLen]), State(state), Protocol(proto), atr[:atrLen], Error(r) +} + +func scardTransmit(card uintptr, proto Protocol, cmd []byte, rsp []byte) (uint32, Error) { + var sendpci uintptr + var rspLen = uint32(len(rsp)) + + switch proto { + case ProtocolT0: + sendpci = scardIoReqT0 + case ProtocolT1: + sendpci = scardIoReqT1 + default: + panic("unknown protocol") + } + + r, _, _ := procTransmit.Call(card, sendpci, uintptr(unsafe.Pointer(&cmd[0])), uintptr(len(cmd)), uintptr(0), uintptr(unsafe.Pointer(&rsp[0])), uintptr(unsafe.Pointer(&rspLen))) + + return rspLen, Error(r) +} + +func scardControl(card uintptr, ioctl uint32, in, out []byte) (uint32, Error) { + var ptrIn uintptr + var outLen = uint32(len(out)) + + if len(in) != 0 { + ptrIn = uintptr(unsafe.Pointer(&in[0])) + } + + r, _, _ := procControl.Call(card, uintptr(ioctl), ptrIn, uintptr(len(in)), uintptr(unsafe.Pointer(&out[0])), uintptr(len(out)), uintptr(unsafe.Pointer(&outLen))) + return outLen, Error(r) +} + +func scardGetAttrib(card uintptr, id Attrib, buf []byte) (uint32, Error) { + var ptr uintptr + + if len(buf) != 0 { + ptr = uintptr(unsafe.Pointer(&buf[0])) + } + + bufLen := uint32(len(buf)) + r, _, _ := procGetAttrib.Call(card, uintptr(id), ptr, uintptr(unsafe.Pointer(&bufLen))) + + return bufLen, Error(r) +} + +func scardSetAttrib(card uintptr, id Attrib, buf []byte) Error { + r, _, _ := procSetAttrib.Call(card, uintptr(id), uintptr(unsafe.Pointer(&buf[0])), uintptr(len(buf))) + return Error(r) +} + +type scardReaderState struct { + szReader uintptr + pvUserData uintptr + dwCurrentState uint32 + dwEventState uint32 + cbAtr uint32 + rgbAtr [36]byte +} + +func (rs *ReaderState) toSys() (scardReaderState, error) { + var sys scardReaderState + creader, err := encodestr(rs.Reader) + if err != nil { + return scardReaderState{}, err + } + sys.szReader = uintptr(creader.ptr()) + sys.dwCurrentState = uint32(rs.CurrentState) + sys.cbAtr = uint32(len(rs.Atr)) + copy(sys.rgbAtr[:], rs.Atr) + 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)) + copy(rs.Atr, sys.rgbAtr[:]) + } +} + +type strbuf []uint16 + +func encodestr(s string) (strbuf, error) { + utf16, err := syscall.UTF16FromString(s) + return strbuf(utf16), err +} + +func decodestr(buf strbuf) string { + return syscall.UTF16ToString(buf) +} diff --git a/vendor/github.com/ebfe/scard/zconst.go b/vendor/github.com/ebfe/scard/zconst.go new file mode 100644 index 000000000..675db21dc --- /dev/null +++ b/vendor/github.com/ebfe/scard/zconst.go @@ -0,0 +1,190 @@ +// Created by cgo -godefs - DO NOT EDIT +// cgo -godefs -- -I /usr/include/PCSC/ const.go + +package scard + +type Attrib uint32 + +const ( + AttrVendorName Attrib = 0x10100 + AttrVendorIfdType Attrib = 0x10101 + AttrVendorIfdVersion Attrib = 0x10102 + AttrVendorIfdSerialNo Attrib = 0x10103 + AttrChannelId Attrib = 0x20110 + AttrAsyncProtocolTypes Attrib = 0x30120 + AttrDefaultClk Attrib = 0x30121 + AttrMaxClk Attrib = 0x30122 + AttrDefaultDataRate Attrib = 0x30123 + AttrMaxDataRate Attrib = 0x30124 + AttrMaxIfsd Attrib = 0x30125 + AttrSyncProtocolTypes Attrib = 0x30126 + AttrPowerMgmtSupport Attrib = 0x40131 + AttrUserToCardAuthDevice Attrib = 0x50140 + AttrUserAuthInputDevice Attrib = 0x50142 + AttrCharacteristics Attrib = 0x60150 + AttrCurrentProtocolType Attrib = 0x80201 + AttrCurrentClk Attrib = 0x80202 + AttrCurrentF Attrib = 0x80203 + AttrCurrentD Attrib = 0x80204 + AttrCurrentN Attrib = 0x80205 + AttrCurrentW Attrib = 0x80206 + AttrCurrentIfsc Attrib = 0x80207 + AttrCurrentIfsd Attrib = 0x80208 + AttrCurrentBwt Attrib = 0x80209 + AttrCurrentCwt Attrib = 0x8020a + AttrCurrentEbcEncoding Attrib = 0x8020b + AttrExtendedBwt Attrib = 0x8020c + AttrIccPresence Attrib = 0x90300 + AttrIccInterfaceStatus Attrib = 0x90301 + AttrCurrentIoState Attrib = 0x90302 + AttrAtrString Attrib = 0x90303 + AttrIccTypePerAtr Attrib = 0x90304 + AttrEscReset Attrib = 0x7a000 + AttrEscCancel Attrib = 0x7a003 + AttrEscAuthrequest Attrib = 0x7a005 + AttrMaxinput Attrib = 0x7a007 + AttrDeviceUnit Attrib = 0x7fff0001 + AttrDeviceInUse Attrib = 0x7fff0002 + AttrDeviceFriendlyName Attrib = 0x7fff0003 + AttrDeviceSystemName Attrib = 0x7fff0004 + AttrSupressT1IfsRequest Attrib = 0x7fff0007 +) + +type Error uint32 + +const ( + ErrSuccess Error = 0x0 + ErrInternalError Error = 0x80100001 + ErrCancelled Error = 0x80100002 + ErrInvalidHandle Error = 0x80100003 + ErrInvalidParameter Error = 0x80100004 + ErrInvalidTarget Error = 0x80100005 + ErrNoMemory Error = 0x80100006 + ErrWaitedTooLong Error = 0x80100007 + ErrInsufficientBuffer Error = 0x80100008 + ErrUnknownReader Error = 0x80100009 + ErrTimeout Error = 0x8010000a + ErrSharingViolation Error = 0x8010000b + ErrNoSmartcard Error = 0x8010000c + ErrUnknownCard Error = 0x8010000d + ErrCantDispose Error = 0x8010000e + ErrProtoMismatch Error = 0x8010000f + ErrNotReady Error = 0x80100010 + ErrInvalidValue Error = 0x80100011 + ErrSystemCancelled Error = 0x80100012 + ErrCommError Error = 0x80100013 + ErrUnknownError Error = 0x80100014 + ErrInvalidAtr Error = 0x80100015 + ErrNotTransacted Error = 0x80100016 + ErrReaderUnavailable Error = 0x80100017 + ErrShutdown Error = 0x80100018 + ErrPciTooSmall Error = 0x80100019 + ErrReaderUnsupported Error = 0x8010001a + ErrDuplicateReader Error = 0x8010001b + ErrCardUnsupported Error = 0x8010001c + ErrNoService Error = 0x8010001d + ErrServiceStopped Error = 0x8010001e + ErrUnexpected Error = 0x8010001f + ErrUnsupportedFeature Error = 0x8010001f + ErrIccInstallation Error = 0x80100020 + ErrIccCreateorder Error = 0x80100021 + ErrFileNotFound Error = 0x80100024 + ErrNoDir Error = 0x80100025 + ErrNoFile Error = 0x80100026 + ErrNoAccess Error = 0x80100027 + ErrWriteTooMany Error = 0x80100028 + ErrBadSeek Error = 0x80100029 + ErrInvalidChv Error = 0x8010002a + ErrUnknownResMng Error = 0x8010002b + ErrNoSuchCertificate Error = 0x8010002c + ErrCertificateUnavailable Error = 0x8010002d + ErrNoReadersAvailable Error = 0x8010002e + ErrCommDataLost Error = 0x8010002f + ErrNoKeyContainer Error = 0x80100030 + ErrServerTooBusy Error = 0x80100031 + ErrUnsupportedCard Error = 0x80100065 + ErrUnresponsiveCard Error = 0x80100066 + ErrUnpoweredCard Error = 0x80100067 + ErrResetCard Error = 0x80100068 + ErrRemovedCard Error = 0x80100069 + ErrSecurityViolation Error = 0x8010006a + ErrWrongChv Error = 0x8010006b + ErrChvBlocked Error = 0x8010006c + ErrEof Error = 0x8010006d + ErrCancelledByUser Error = 0x8010006e + ErrCardNotAuthenticated Error = 0x8010006f +) + +type Protocol uint32 + +const ( + ProtocolUndefined Protocol = 0x0 + ProtocolT0 Protocol = 0x1 + ProtocolT1 Protocol = 0x2 + ProtocolAny Protocol = ProtocolT0 | ProtocolT1 +) + +type ShareMode uint32 + +const ( + ShareExclusive ShareMode = 0x1 + ShareShared ShareMode = 0x2 + ShareDirect ShareMode = 0x3 +) + +type Disposition uint32 + +const ( + LeaveCard Disposition = 0x0 + ResetCard Disposition = 0x1 + UnpowerCard Disposition = 0x2 + EjectCard Disposition = 0x3 +) + +type Scope uint32 + +const ( + ScopeUser Scope = 0x0 + ScopeTerminal Scope = 0x1 + ScopeSystem Scope = 0x2 +) + +type State uint32 + +const ( + Unknown State = 0x1 + Absent State = 0x2 + Present State = 0x4 + Swallowed State = 0x8 + Powered State = 0x10 + Negotiable State = 0x20 + Specific State = 0x40 +) + +type StateFlag uint32 + +const ( + StateUnaware StateFlag = 0x0 + StateIgnore StateFlag = 0x1 + StateChanged StateFlag = 0x2 + StateUnknown StateFlag = 0x4 + StateUnavailable StateFlag = 0x8 + StateEmpty StateFlag = 0x10 + StatePresent StateFlag = 0x20 + StateAtrmatch StateFlag = 0x40 + StateExclusive StateFlag = 0x80 + StateInuse StateFlag = 0x100 + StateMute StateFlag = 0x200 + StateUnpowered StateFlag = 0x400 +) + +const ( + maxBufferSize = 0x108 + maxBufferSizeExtended = 0x1000c + maxReadername = 0x80 + maxAtrSize = 0x21 +) + +const ( + infiniteTimeout = 0xffffffff +) |