vendor: upgrade go-libpcsclite (#19420)

* vendor: remove leftover trace

* Upgrade go-libpcsclite to the latest version
pull/19426/head
Guillaume Ballet 6 years ago committed by Péter Szilágyi
parent 33d28f37c7
commit cf1a6d7c56
  1. 34
      vendor/github.com/gballet/go-libpcsclite/README.md
  2. 6
      vendor/github.com/gballet/go-libpcsclite/doc.go
  3. 246
      vendor/github.com/gballet/go-libpcsclite/error.go
  4. 87
      vendor/github.com/gballet/go-libpcsclite/winscard.go
  5. 6
      vendor/vendor.json

@ -6,18 +6,38 @@ A golang implementation of the [libpcpsclite](http://github.com/LudovicRousseau/
The goal is for major open source projects to distribute a single binary that doesn't depend on `libpcsclite`. It provides an extra function `CheckPCSCDaemon` that will tell the user if `pcscd` is running.
## Building
## Example
TODO
```golang
func main() {
client, err := EstablishContext(2)
if err != nil {
fmt.Printf("Error establishing context: %v\n", err)
os.Exit(1)
}
## Example
_, err = client.ListReaders()
if err != nil {
fmt.Printf("Error getting the list of readers: %v\n", err)
os.Exit(1)
}
card, err := client.Connect(client.readerStateDescriptors[0].Name, ShareShared, ProtocolT0|ProtocolT1)
if err != nil {
fmt.Printf("Error connecting: %v\n", err)
os.Exit(1)
}
resp, _, err := card.Transmit([]byte{0, 0xa4, 4, 0, 0xA0, 0, 0, 8, 4, 0, 1, 1, 0, 0, 0, 0, 0, 0, 0})
TODO
card.Disconnect(LeaveCard)
}
```
## TODO
- [ ] Finish this README
- [ ] Lock context
- [x] Finish this README
- [x] Lock context
- [ ] implement missing functions
## License
@ -50,4 +70,4 @@ 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.
OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.

@ -31,8 +31,6 @@
package pcsc
const (
SCardSuccess = 0x00000000 /* No error was encountered. */
AutoAllocate = -1 /* see SCardFreeMemory() */
ScopeUser = 0x0000 /* Scope in user space */
ScopeTerminal = 0x0001 /* Scope in terminal */
@ -94,6 +92,6 @@ const (
// Protocol information
const (
ProtocolVersionMajor = 4 /* IPC major */
ProtocolVersionMinor = 3 /* IPC minor */
ProtocolVersionMajor = uint32(4) /* IPC major */
ProtocolVersionMinor = uint32(3) /* IPC minor */
)

@ -0,0 +1,246 @@
// BSD 3-Clause License
//
// Copyright (c) 2019, Guillaume Ballet
// 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.
//
// * Neither the name of the copyright holder nor the names of its
// contributors may be used to endorse or promote products derived from
// this software without specific prior written permission.
//
// 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.
package pcsc
import "fmt"
type ErrorCode uint32
const (
SCardSuccess ErrorCode = 0x00000000 /* No error was encountered. */
ErrSCardInternal = 0x80100001 /* An internal consistency check failed. */
ErrSCardCancelled = 0x80100002 /* The action was cancelled by an SCardCancel request. */
ErrSCardInvalidHandle = 0x80100003 /* The supplied handle was invalid. */
ErrSCardInvalidParameter = 0x80100004 /* One or more of the supplied parameters could not be properly interpreted. */
ErrSCardInvalidTarget = 0x80100005 /* Registry startup information is missing or invalid. */
ErrSCardNoMemory = 0x80100006 /* Not enough memory available to complete this command. */
ErrSCardWaitedTooLong = 0x80100007 /* An internal consistency timer has expired. */
ErrSCardInsufficientBuffer = 0x80100008 /* The data buffer to receive returned data is too small for the returned data. */
ErrScardUnknownReader = 0x80100009 /* The specified reader name is not recognized. */
ErrSCardTimeout = 0x8010000A /* The user-specified timeout value has expired. */
ErrSCardSharingViolation = 0x8010000B /* The smart card cannot be accessed because of other connections outstanding. */
ErrSCardNoSmartCard = 0x8010000C /* The operation requires a Smart Card, but no Smart Card is currently in the device. */
ErrSCardUnknownCard = 0x8010000D /* The specified smart card name is not recognized. */
ErrSCardCannotDispose = 0x8010000E /* The system could not dispose of the media in the requested manner. */
ErrSCardProtoMismatch = 0x8010000F /* The requested protocols are incompatible with the protocol currently in use with the smart card. */
ErrSCardNotReady = 0x80100010 /* The reader or smart card is not ready to accept commands. */
ErrSCardInvalidValue = 0x80100011 /* One or more of the supplied parameters values could not be properly interpreted. */
ErrSCardSystemCancelled = 0x80100012 /* The action was cancelled by the system, presumably to log off or shut down. */
ErrSCardCommError = 0x80100013 /* An internal communications error has been detected. */
ErrScardUnknownError = 0x80100014 /* An internal error has been detected, but the source is unknown. */
ErrSCardInvalidATR = 0x80100015 /* An ATR obtained from the registry is not a valid ATR string. */
ErrSCardNotTransacted = 0x80100016 /* An attempt was made to end a non-existent transaction. */
ErrSCardReaderUnavailable = 0x80100017 /* The specified reader is not currently available for use. */
ErrSCardShutdown = 0x80100018 /* The operation has been aborted to allow the server application to exit. */
ErrSCardPCITooSmall = 0x80100019 /* The PCI Receive buffer was too small. */
ErrSCardReaderUnsupported = 0x8010001A /* The reader driver does not meet minimal requirements for support. */
ErrSCardDuplicateReader = 0x8010001B /* The reader driver did not produce a unique reader name. */
ErrSCardCardUnsupported = 0x8010001C /* The smart card does not meet minimal requirements for support. */
ErrScardNoService = 0x8010001D /* The Smart card resource manager is not running. */
ErrSCardServiceStopped = 0x8010001E /* The Smart card resource manager has shut down. */
ErrSCardUnexpected = 0x8010001F /* An unexpected card error has occurred. */
ErrSCardUnsupportedFeature = 0x8010001F /* This smart card does not support the requested feature. */
ErrSCardICCInstallation = 0x80100020 /* No primary provider can be found for the smart card. */
ErrSCardICCCreateOrder = 0x80100021 /* The requested order of object creation is not supported. */
ErrSCardDirNotFound = 0x80100023 /* The identified directory does not exist in the smart card. */
ErrSCardFileNotFound = 0x80100024 /* The identified file does not exist in the smart card. */
ErrSCardNoDir = 0x80100025 /* The supplied path does not represent a smart card directory. */
ErrSCardNoFile = 0x80100026 /* The supplied path does not represent a smart card file. */
ErrScardNoAccess = 0x80100027 /* Access is denied to this file. */
ErrSCardWriteTooMany = 0x80100028 /* The smart card does not have enough memory to store the information. */
ErrSCardBadSeek = 0x80100029 /* There was an error trying to set the smart card file object pointer. */
ErrSCardInvalidCHV = 0x8010002A /* The supplied PIN is incorrect. */
ErrSCardUnknownResMNG = 0x8010002B /* An unrecognized error code was returned from a layered component. */
ErrSCardNoSuchCertificate = 0x8010002C /* The requested certificate does not exist. */
ErrSCardCertificateUnavailable = 0x8010002D /* The requested certificate could not be obtained. */
ErrSCardNoReadersAvailable = 0x8010002E /* Cannot find a smart card reader. */
ErrSCardCommDataLost = 0x8010002F /* A communications error with the smart card has been detected. Retry the operation. */
ErrScardNoKeyContainer = 0x80100030 /* The requested key container does not exist on the smart card. */
ErrSCardServerTooBusy = 0x80100031 /* The Smart Card Resource Manager is too busy to complete this operation. */
ErrSCardUnsupportedCard = 0x80100065 /* The reader cannot communicate with the card, due to ATR string configuration conflicts. */
ErrSCardUnresponsiveCard = 0x80100066 /* The smart card is not responding to a reset. */
ErrSCardUnpoweredCard = 0x80100067 /* Power has been removed from the smart card, so that further communication is not possible. */
ErrSCardResetCard = 0x80100068 /* The smart card has been reset, so any shared state information is invalid. */
ErrSCardRemovedCard = 0x80100069 /* The smart card has been removed, so further communication is not possible. */
ErrSCardSecurityViolation = 0x8010006A /* Access was denied because of a security violation. */
ErrSCardWrongCHV = 0x8010006B /* The card cannot be accessed because the wrong PIN was presented. */
ErrSCardCHVBlocked = 0x8010006C /* The card cannot be accessed because the maximum number of PIN entry attempts has been reached. */
ErrSCardEOF = 0x8010006D /* The end of the smart card file has been reached. */
ErrSCardCancelledByUser = 0x8010006E /* The user pressed "Cancel" on a Smart Card Selection Dialog. */
ErrSCardCardNotAuthenticated = 0x8010006F /* No PIN was presented to the smart card. */
)
// Code returns the error code, with an uint32 type to be used in PutUInt32
func (code ErrorCode) Code() uint32 {
return uint32(code)
}
func (code ErrorCode) Error() error {
switch code {
case SCardSuccess:
return fmt.Errorf("Command successful")
case ErrSCardInternal:
return fmt.Errorf("Internal error")
case ErrSCardCancelled:
return fmt.Errorf("Command cancelled")
case ErrSCardInvalidHandle:
return fmt.Errorf("Invalid handle")
case ErrSCardInvalidParameter:
return fmt.Errorf("Invalid parameter given")
case ErrSCardInvalidTarget:
return fmt.Errorf("Invalid target given")
case ErrSCardNoMemory:
return fmt.Errorf("Not enough memory")
case ErrSCardWaitedTooLong:
return fmt.Errorf("Waited too long")
case ErrSCardInsufficientBuffer:
return fmt.Errorf("Insufficient buffer")
case ErrScardUnknownReader:
return fmt.Errorf("Unknown reader specified")
case ErrSCardTimeout:
return fmt.Errorf("Command timeout")
case ErrSCardSharingViolation:
return fmt.Errorf("Sharing violation")
case ErrSCardNoSmartCard:
return fmt.Errorf("No smart card inserted")
case ErrSCardUnknownCard:
return fmt.Errorf("Unknown card")
case ErrSCardCannotDispose:
return fmt.Errorf("Cannot dispose handle")
case ErrSCardProtoMismatch:
return fmt.Errorf("Card protocol mismatch")
case ErrSCardNotReady:
return fmt.Errorf("Subsystem not ready")
case ErrSCardInvalidValue:
return fmt.Errorf("Invalid value given")
case ErrSCardSystemCancelled:
return fmt.Errorf("System cancelled")
case ErrSCardCommError:
return fmt.Errorf("RPC transport error")
case ErrScardUnknownError:
return fmt.Errorf("Unknown error")
case ErrSCardInvalidATR:
return fmt.Errorf("Invalid ATR")
case ErrSCardNotTransacted:
return fmt.Errorf("Transaction failed")
case ErrSCardReaderUnavailable:
return fmt.Errorf("Reader is unavailable")
/* case SCARD_P_SHUTDOWN: */
case ErrSCardPCITooSmall:
return fmt.Errorf("PCI struct too small")
case ErrSCardReaderUnsupported:
return fmt.Errorf("Reader is unsupported")
case ErrSCardDuplicateReader:
return fmt.Errorf("Reader already exists")
case ErrSCardCardUnsupported:
return fmt.Errorf("Card is unsupported")
case ErrScardNoService:
return fmt.Errorf("Service not available")
case ErrSCardServiceStopped:
return fmt.Errorf("Service was stopped")
/* case SCARD_E_UNEXPECTED: */
/* case SCARD_E_ICC_CREATEORDER: */
/* case SCARD_E_UNSUPPORTED_FEATURE: */
/* case SCARD_E_DIR_NOT_FOUND: */
/* case SCARD_E_NO_DIR: */
/* case SCARD_E_NO_FILE: */
/* case SCARD_E_NO_ACCESS: */
/* case SCARD_E_WRITE_TOO_MANY: */
/* case SCARD_E_BAD_SEEK: */
/* case SCARD_E_INVALID_CHV: */
/* case SCARD_E_UNKNOWN_RES_MNG: */
/* case SCARD_E_NO_SUCH_CERTIFICATE: */
/* case SCARD_E_CERTIFICATE_UNAVAILABLE: */
case ErrSCardNoReadersAvailable:
return fmt.Errorf("Cannot find a smart card reader")
/* case SCARD_E_COMM_DATA_LOST: */
/* case SCARD_E_NO_KEY_CONTAINER: */
/* case SCARD_E_SERVER_TOO_BUSY: */
case ErrSCardUnsupportedCard:
return fmt.Errorf("Card is not supported")
case ErrSCardUnresponsiveCard:
return fmt.Errorf("Card is unresponsive")
case ErrSCardUnpoweredCard:
return fmt.Errorf("Card is unpowered")
case ErrSCardResetCard:
return fmt.Errorf("Card was reset")
case ErrSCardRemovedCard:
return fmt.Errorf("Card was removed")
/* case SCARD_W_SECURITY_VIOLATION: */
/* case SCARD_W_WRONG_CHV: */
/* case SCARD_W_CHV_BLOCKED: */
/* case SCARD_W_EOF: */
/* case SCARD_W_CANCELLED_BY_USER: */
/* case SCARD_W_CARD_NOT_AUTHENTICATED: */
case ErrSCardUnsupportedFeature:
return fmt.Errorf("Feature not supported")
default:
return fmt.Errorf("unknown error: %08x", code)
}
}

@ -65,43 +65,56 @@ func EstablishContext(scope uint32) (*Client, error) {
}
client.conn = conn
/* Exchange version information */
payload := make([]byte, 12)
binary.LittleEndian.PutUint32(payload, ProtocolVersionMajor)
binary.LittleEndian.PutUint32(payload[4:], ProtocolVersionMinor)
binary.LittleEndian.PutUint32(payload[8:], SCardSuccess)
err = messageSendWithHeader(CommandVersion, conn, payload)
if err != nil {
return nil, err
}
response := make([]byte, 12)
n, err := conn.Read(response)
if err != nil {
return nil, err
}
if n != len(response) {
return nil, fmt.Errorf("invalid response length: expected %d, got %d", len(response), n)
var code uint32
var minor uint32
for minor = ProtocolVersionMinor; minor <= ProtocolVersionMinor+1; minor++ {
/* Exchange version information */
binary.LittleEndian.PutUint32(payload, ProtocolVersionMajor)
binary.LittleEndian.PutUint32(payload[4:], minor)
binary.LittleEndian.PutUint32(payload[8:], SCardSuccess.Code())
err = messageSendWithHeader(CommandVersion, conn, payload)
if err != nil {
return nil, err
}
n, err := conn.Read(response)
if err != nil {
return nil, err
}
if n != len(response) {
return nil, fmt.Errorf("invalid response length: expected %d, got %d", len(response), n)
}
code = binary.LittleEndian.Uint32(response[8:])
if code != SCardSuccess.Code() {
continue
}
client.major = binary.LittleEndian.Uint32(response)
client.minor = binary.LittleEndian.Uint32(response[4:])
if client.major != ProtocolVersionMajor || client.minor != minor {
continue
}
break
}
code := binary.LittleEndian.Uint32(response[8:])
if code != SCardSuccess {
return nil, fmt.Errorf("invalid response code: expected %d, got %d", SCardSuccess, code)
if code != SCardSuccess.Code() {
return nil, fmt.Errorf("invalid response code: expected %d, got %d (%v)", SCardSuccess, code, ErrorCode(code).Error())
}
client.major = binary.LittleEndian.Uint32(response)
client.minor = binary.LittleEndian.Uint32(response[4:])
if client.major != ProtocolVersionMajor || client.minor != ProtocolVersionMinor {
if client.major != ProtocolVersionMajor || (client.minor != minor && client.minor+1 != minor) {
return nil, fmt.Errorf("invalid version found: expected %d.%d, got %d.%d", ProtocolVersionMajor, ProtocolVersionMinor, client.major, client.minor)
}
/* Establish the context proper */
binary.LittleEndian.PutUint32(payload, scope)
binary.LittleEndian.PutUint32(payload[4:], 0)
binary.LittleEndian.PutUint32(payload[8:], SCardSuccess)
binary.LittleEndian.PutUint32(payload[8:], SCardSuccess.Code())
err = messageSendWithHeader(SCardEstablishContext, conn, payload)
if err != nil {
return nil, err
}
response = make([]byte, 12)
n, err = conn.Read(response)
n, err := conn.Read(response)
if err != nil {
return nil, err
}
@ -109,8 +122,8 @@ func EstablishContext(scope uint32) (*Client, error) {
return nil, fmt.Errorf("invalid response length: expected %d, got %d", len(response), n)
}
code = binary.LittleEndian.Uint32(response[8:])
if code != SCardSuccess {
return nil, fmt.Errorf("invalid response code: expected %d, got %d", SCardSuccess, code)
if code != SCardSuccess.Code() {
return nil, fmt.Errorf("invalid response code: expected %d, got %d (%v)", SCardSuccess, code, ErrorCode(code).Error())
}
client.ctx = binary.LittleEndian.Uint32(response[4:])
@ -125,7 +138,7 @@ func (client *Client) ReleaseContext() error {
data := [8]byte{}
binary.LittleEndian.PutUint32(data[:], client.ctx)
binary.LittleEndian.PutUint32(data[4:], SCardSuccess)
binary.LittleEndian.PutUint32(data[4:], SCardSuccess.Code())
err := messageSendWithHeader(SCardReleaseContext, client.conn, data[:])
if err != nil {
return err
@ -139,8 +152,8 @@ func (client *Client) ReleaseContext() error {
total += n
}
code := binary.LittleEndian.Uint32(data[4:])
if code != SCardSuccess {
return fmt.Errorf("invalid return code: %x", code)
if code != SCardSuccess.Code() {
return fmt.Errorf("invalid return code: %x, %v", code, ErrorCode(code).Error())
}
return nil
@ -247,7 +260,7 @@ func (client *Client) Connect(name string, shareMode uint32, preferredProtocol u
copy(request[SCardConnectReaderNameOffset:], []byte(name))
binary.LittleEndian.PutUint32(request[SCardConnectShareModeOffset:], shareMode)
binary.LittleEndian.PutUint32(request[SCardConnectPreferredProtocolOffset:], preferredProtocol)
binary.LittleEndian.PutUint32(request[SCardConnectReturnValueOffset:], SCardSuccess)
binary.LittleEndian.PutUint32(request[SCardConnectReturnValueOffset:], SCardSuccess.Code())
err := messageSendWithHeader(SCardConnect, client.conn, request)
if err != nil {
@ -260,12 +273,12 @@ func (client *Client) Connect(name string, shareMode uint32, preferredProtocol u
if err != nil {
return nil, err
}
fmt.Println("total, n", total, n, response)
// fmt.Println("total, n", total, n, response)
total += n
}
code := binary.LittleEndian.Uint32(response[148:])
if code != SCardSuccess {
return nil, fmt.Errorf("invalid return code: %x", code)
if code != SCardSuccess.Code() {
return nil, fmt.Errorf("invalid return code: %x (%v)", code, ErrorCode(code).Error())
}
handle := binary.LittleEndian.Uint32(response[140:])
active := binary.LittleEndian.Uint32(response[SCardConnectPreferredProtocolOffset:])
@ -312,7 +325,7 @@ func (card *Card) Transmit(adpu []byte) ([]byte, *SCardIoRequest, error) {
binary.LittleEndian.PutUint32(request[16:], 0)
binary.LittleEndian.PutUint32(request[20:], 0)
binary.LittleEndian.PutUint32(request[24:], 0x10000)
binary.LittleEndian.PutUint32(request[28:], SCardSuccess)
binary.LittleEndian.PutUint32(request[28:], SCardSuccess.Code())
err := messageSendWithHeader(SCardTransmit, card.client.conn, request[:])
if err != nil {
return nil, nil, err
@ -336,8 +349,8 @@ func (card *Card) Transmit(adpu []byte) ([]byte, *SCardIoRequest, error) {
}
code := binary.LittleEndian.Uint32(response[28:])
if code != SCardSuccess {
return nil, nil, fmt.Errorf("invalid return code: %x", code)
if code != SCardSuccess.Code() {
return nil, nil, fmt.Errorf("invalid return code: %x (%v)", code, ErrorCode(code).Error())
}
// Recover the response data
@ -367,7 +380,7 @@ func (card *Card) Disconnect(disposition uint32) error {
data := [12]byte{}
binary.LittleEndian.PutUint32(data[:], card.handle)
binary.LittleEndian.PutUint32(data[4:], disposition)
binary.LittleEndian.PutUint32(data[8:], SCardSuccess)
binary.LittleEndian.PutUint32(data[8:], SCardSuccess.Code())
err := messageSendWithHeader(SCardDisConnect, card.client.conn, data[:])
if err != nil {
return err
@ -381,8 +394,8 @@ func (card *Card) Disconnect(disposition uint32) error {
total += n
}
code := binary.LittleEndian.Uint32(data[8:])
if code != SCardSuccess {
return fmt.Errorf("invalid return code: %x", code)
if code != SCardSuccess.Code() {
return fmt.Errorf("invalid return code: %x (%v)", code, ErrorCode(code).Error())
}
return nil

@ -140,10 +140,10 @@
"revisionTime": "2018-04-18T12:24:29Z"
},
{
"checksumSHA1": "GnNfMrYs/4m+HCtDBF7HpPUFFVw=",
"checksumSHA1": "GXqHzd0XkPLX/iulpOncaxbxzZo=",
"path": "github.com/gballet/go-libpcsclite",
"revision": "95b81846253cd854b8bb8f2fd9cc6056d0681ac4",
"revisionTime": "2019-03-13T11:40:44Z"
"revision": "312b5175032f98274685a4dd81935a92ad2412a5",
"revisionTime": "2019-04-03T18:15:18Z"
},
{
"checksumSHA1": "gxV/cPPLkByTdY8y172t7v4qcZA=",

Loading…
Cancel
Save