accounts, core, internal, node: Add support for smartcard wallets
This commit is contained in:
committed by
Guillaume Ballet
parent
3996bc1ad9
commit
f7027dd68c
221
vendor/github.com/ebfe/scard/scard_windows.go
generated
vendored
Normal file
221
vendor/github.com/ebfe/scard/scard_windows.go
generated
vendored
Normal 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)
|
||||
}
|
Reference in New Issue
Block a user