diff --git a/vendor/github.com/gballet/go-libpcsclite/README.md b/vendor/github.com/gballet/go-libpcsclite/README.md index baca30ff8..182398e39 100644 --- a/vendor/github.com/gballet/go-libpcsclite/README.md +++ b/vendor/github.com/gballet/go-libpcsclite/README.md @@ -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 - -TODO - ## Example -TODO +```golang +func main() { + client, err := EstablishContext(2) + if err != nil { + fmt.Printf("Error establishing context: %v\n", err) + os.Exit(1) + } + + _, 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}) + + 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. \ No newline at end of file +OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. diff --git a/vendor/github.com/gballet/go-libpcsclite/doc.go b/vendor/github.com/gballet/go-libpcsclite/doc.go index 394957909..d1085319a 100644 --- a/vendor/github.com/gballet/go-libpcsclite/doc.go +++ b/vendor/github.com/gballet/go-libpcsclite/doc.go @@ -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 */ ) diff --git a/vendor/github.com/gballet/go-libpcsclite/error.go b/vendor/github.com/gballet/go-libpcsclite/error.go new file mode 100644 index 000000000..4710de5e6 --- /dev/null +++ b/vendor/github.com/gballet/go-libpcsclite/error.go @@ -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) + } +} diff --git a/vendor/github.com/gballet/go-libpcsclite/winscard.go b/vendor/github.com/gballet/go-libpcsclite/winscard.go index 8c6f65d28..e4692ed16 100644 --- a/vendor/github.com/gballet/go-libpcsclite/winscard.go +++ b/vendor/github.com/gballet/go-libpcsclite/winscard.go @@ -65,16 +65,55 @@ 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) + response := make([]byte, 12) + + 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 + } + + if code != SCardSuccess.Code() { + return nil, fmt.Errorf("invalid response code: expected %d, got %d (%v)", SCardSuccess, code, ErrorCode(code).Error()) + } + 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.Code()) + err = messageSendWithHeader(SCardEstablishContext, conn, payload) if err != nil { return nil, err } - response := make([]byte, 12) + response = make([]byte, 12) n, err := conn.Read(response) if err != nil { return nil, err @@ -82,35 +121,9 @@ func EstablishContext(scope uint32) (*Client, error) { 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 { - return nil, fmt.Errorf("invalid response code: expected %d, got %d", SCardSuccess, code) - } - client.major = binary.LittleEndian.Uint32(response) - client.minor = binary.LittleEndian.Uint32(response[4:]) - if client.major != ProtocolVersionMajor || client.minor != ProtocolVersionMinor { - 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) - err = messageSendWithHeader(SCardEstablishContext, 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) - } 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 diff --git a/vendor/vendor.json b/vendor/vendor.json index 5412fcfd0..3b20f69f0 100644 --- a/vendor/vendor.json +++ b/vendor/vendor.json @@ -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=",