accounts, core, internal, node: Add support for smartcard wallets

This commit is contained in:
Nick Johnson
2018-01-07 18:38:11 +00:00
committed by Guillaume Ballet
parent 3996bc1ad9
commit f7027dd68c
21 changed files with 5364 additions and 0 deletions

23
vendor/github.com/ebfe/scard/LICENSE generated vendored Normal file
View File

@@ -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.

14
vendor/github.com/ebfe/scard/README.md generated vendored Normal file
View File

@@ -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.

283
vendor/github.com/ebfe/scard/scard.go generated vendored Normal file
View File

@@ -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
}

219
vendor/github.com/ebfe/scard/scard_darwin.go generated vendored Normal file
View File

@@ -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])
}
}
}

206
vendor/github.com/ebfe/scard/scard_unix.go generated vendored Normal file
View File

@@ -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])
}
}
}

221
vendor/github.com/ebfe/scard/scard_windows.go generated vendored Normal file
View File

@@ -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)
}

190
vendor/github.com/ebfe/scard/zconst.go generated vendored Normal file
View File

@@ -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
)