12
vendor/github.com/gballet/go-libpcsclite/.gitignore
generated
vendored
Normal file
12
vendor/github.com/gballet/go-libpcsclite/.gitignore
generated
vendored
Normal file
@@ -0,0 +1,12 @@
|
||||
# Binaries for programs and plugins
|
||||
*.exe
|
||||
*.exe~
|
||||
*.dll
|
||||
*.so
|
||||
*.dylib
|
||||
|
||||
# Test binary, build with `go test -c`
|
||||
*.test
|
||||
|
||||
# Output of the go coverage tool, specifically when used with LiteIDE
|
||||
*.out
|
||||
29
vendor/github.com/gballet/go-libpcsclite/LICENSE
generated
vendored
Normal file
29
vendor/github.com/gballet/go-libpcsclite/LICENSE
generated
vendored
Normal file
@@ -0,0 +1,29 @@
|
||||
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.
|
||||
73
vendor/github.com/gballet/go-libpcsclite/README.md
generated
vendored
Normal file
73
vendor/github.com/gballet/go-libpcsclite/README.md
generated
vendored
Normal file
@@ -0,0 +1,73 @@
|
||||
# go-libpcsclite
|
||||
|
||||
A golang implementation of the [libpcpsclite](http://github.com/LudovicRousseau/PCSC) client. It connects to the `pcscd` daemon over sockets.
|
||||
|
||||
## Purpose
|
||||
|
||||
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.
|
||||
|
||||
## Example
|
||||
|
||||
```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
|
||||
|
||||
- [x] Finish this README
|
||||
- [x] Lock context
|
||||
- [ ] implement missing functions
|
||||
|
||||
## License
|
||||
|
||||
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.
|
||||
95
vendor/github.com/gballet/go-libpcsclite/doc.go
generated
vendored
Normal file
95
vendor/github.com/gballet/go-libpcsclite/doc.go
generated
vendored
Normal file
@@ -0,0 +1,95 @@
|
||||
// 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
|
||||
|
||||
const (
|
||||
AutoAllocate = -1 /* see SCardFreeMemory() */
|
||||
ScopeUser = 0x0000 /* Scope in user space */
|
||||
ScopeTerminal = 0x0001 /* Scope in terminal */
|
||||
ScopeSystem = 0x0002 /* Scope in system */
|
||||
ScopeGlobal = 0x0003 /* Scope is global */
|
||||
|
||||
ProtocolUndefined = 0x0000 /* protocol not set */
|
||||
ProtocolUnSet = ProtocolUndefined /* backward compat */
|
||||
ProtocolT0 = 0x0001 /* T=0 active protocol. */
|
||||
ProtocolT1 = 0x0002 /* T=1 active protocol. */
|
||||
ProtocolRaw = 0x0004 /* Raw active protocol. */
|
||||
ProtocolT15 = 0x0008 /* T=15 protocol. */
|
||||
ProtocolAny = (ProtocolT0 | ProtocolT1) /* IFD determines prot. */
|
||||
|
||||
ShareExclusive = 0x0001 /* Exclusive mode only */
|
||||
ShareShared = 0x0002 /* Shared mode only */
|
||||
ShareDirect = 0x0003 /* Raw mode only */
|
||||
|
||||
LeaveCard = 0x0000 /* Do nothing on close */
|
||||
ResetCard = 0x0001 /* Reset on close */
|
||||
UnpowerCard = 0x0002 /* Power down on close */
|
||||
EjectCard = 0x0003 /* Eject on close */
|
||||
|
||||
SCardUnknown = 0x0001 /* Unknown state */
|
||||
SCardAbsent = 0x0002 /* Card is absent */
|
||||
SCardPresent = 0x0004 /* Card is present */
|
||||
SCardSwallowed = 0x0008 /* Card not powered */
|
||||
SCardPowever = 0x0010 /* Card is powered */
|
||||
SCardNegotiable = 0x0020 /* Ready for PTS */
|
||||
SCardSpecific = 0x0040 /* PTS has been set */
|
||||
)
|
||||
|
||||
// List of commands to send to the daemon
|
||||
const (
|
||||
_ = iota
|
||||
SCardEstablishContext /* used by SCardEstablishContext() */
|
||||
SCardReleaseContext /* used by SCardReleaseContext() */
|
||||
SCardListReaders /* used by SCardListReaders() */
|
||||
SCardConnect /* used by SCardConnect() */
|
||||
SCardReConnect /* used by SCardReconnect() */
|
||||
SCardDisConnect /* used by SCardDisconnect() */
|
||||
SCardBeginTransaction /* used by SCardBeginTransaction() */
|
||||
SCardEndTransaction /* used by SCardEndTransaction() */
|
||||
SCardTransmit /* used by SCardTransmit() */
|
||||
SCardControl /* used by SCardControl() */
|
||||
SCardStatus /* used by SCardStatus() */
|
||||
SCardGetStatusChange /* not used */
|
||||
SCardCancel /* used by SCardCancel() */
|
||||
SCardCancelTransaction /* not used */
|
||||
SCardGetAttrib /* used by SCardGetAttrib() */
|
||||
SCardSetAttrib /* used by SCardSetAttrib() */
|
||||
CommandVersion /* get the client/server protocol version */
|
||||
CommandGetReaderState /* get the readers state */
|
||||
CommandWaitReaderStateChange /* wait for a reader state change */
|
||||
CommandStopWaitingReaderStateChange /* stop waiting for a reader state change */
|
||||
)
|
||||
|
||||
// Protocol information
|
||||
const (
|
||||
ProtocolVersionMajor = uint32(4) /* IPC major */
|
||||
ProtocolVersionMinor = uint32(3) /* IPC minor */
|
||||
)
|
||||
35
vendor/github.com/gballet/go-libpcsclite/doc_bsd.go
generated
vendored
Normal file
35
vendor/github.com/gballet/go-libpcsclite/doc_bsd.go
generated
vendored
Normal file
@@ -0,0 +1,35 @@
|
||||
// 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.
|
||||
|
||||
// +build dragonfly freebsd netbsd openbsd solaris
|
||||
|
||||
package pcsc
|
||||
|
||||
const PCSCDSockName string = "/var/run/pcscd/pcscd.comm"
|
||||
35
vendor/github.com/gballet/go-libpcsclite/doc_darwin.go
generated
vendored
Normal file
35
vendor/github.com/gballet/go-libpcsclite/doc_darwin.go
generated
vendored
Normal file
@@ -0,0 +1,35 @@
|
||||
// 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.
|
||||
|
||||
// +build darwin
|
||||
|
||||
package pcsc
|
||||
|
||||
const PCSCDSockName string = ""
|
||||
35
vendor/github.com/gballet/go-libpcsclite/doc_linux.go
generated
vendored
Normal file
35
vendor/github.com/gballet/go-libpcsclite/doc_linux.go
generated
vendored
Normal file
@@ -0,0 +1,35 @@
|
||||
// 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.
|
||||
|
||||
// +build linux
|
||||
|
||||
package pcsc
|
||||
|
||||
const PCSCDSockName string = "/run/pcscd/pcscd.comm"
|
||||
35
vendor/github.com/gballet/go-libpcsclite/doc_windows.go
generated
vendored
Normal file
35
vendor/github.com/gballet/go-libpcsclite/doc_windows.go
generated
vendored
Normal file
@@ -0,0 +1,35 @@
|
||||
// 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.
|
||||
|
||||
// +build windows
|
||||
|
||||
package pcsc
|
||||
|
||||
const PCSCDSockName string = ""
|
||||
246
vendor/github.com/gballet/go-libpcsclite/error.go
generated
vendored
Normal file
246
vendor/github.com/gballet/go-libpcsclite/error.go
generated
vendored
Normal file
@@ -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 ErrorCode = 0x80100001 /* An internal consistency check failed. */
|
||||
ErrSCardCancelled ErrorCode = 0x80100002 /* The action was cancelled by an SCardCancel request. */
|
||||
ErrSCardInvalidHandle ErrorCode = 0x80100003 /* The supplied handle was invalid. */
|
||||
ErrSCardInvalidParameter ErrorCode = 0x80100004 /* One or more of the supplied parameters could not be properly interpreted. */
|
||||
ErrSCardInvalidTarget ErrorCode = 0x80100005 /* Registry startup information is missing or invalid. */
|
||||
ErrSCardNoMemory ErrorCode = 0x80100006 /* Not enough memory available to complete this command. */
|
||||
ErrSCardWaitedTooLong ErrorCode = 0x80100007 /* An internal consistency timer has expired. */
|
||||
ErrSCardInsufficientBuffer ErrorCode = 0x80100008 /* The data buffer to receive returned data is too small for the returned data. */
|
||||
ErrScardUnknownReader ErrorCode = 0x80100009 /* The specified reader name is not recognized. */
|
||||
ErrSCardTimeout ErrorCode = 0x8010000A /* The user-specified timeout value has expired. */
|
||||
ErrSCardSharingViolation ErrorCode = 0x8010000B /* The smart card cannot be accessed because of other connections outstanding. */
|
||||
ErrSCardNoSmartCard ErrorCode = 0x8010000C /* The operation requires a Smart Card, but no Smart Card is currently in the device. */
|
||||
ErrSCardUnknownCard ErrorCode = 0x8010000D /* The specified smart card name is not recognized. */
|
||||
ErrSCardCannotDispose ErrorCode = 0x8010000E /* The system could not dispose of the media in the requested manner. */
|
||||
ErrSCardProtoMismatch ErrorCode = 0x8010000F /* The requested protocols are incompatible with the protocol currently in use with the smart card. */
|
||||
ErrSCardNotReady ErrorCode = 0x80100010 /* The reader or smart card is not ready to accept commands. */
|
||||
ErrSCardInvalidValue ErrorCode = 0x80100011 /* One or more of the supplied parameters values could not be properly interpreted. */
|
||||
ErrSCardSystemCancelled ErrorCode = 0x80100012 /* The action was cancelled by the system, presumably to log off or shut down. */
|
||||
ErrSCardCommError ErrorCode = 0x80100013 /* An internal communications error has been detected. */
|
||||
ErrScardUnknownError ErrorCode = 0x80100014 /* An internal error has been detected, but the source is unknown. */
|
||||
ErrSCardInvalidATR ErrorCode = 0x80100015 /* An ATR obtained from the registry is not a valid ATR string. */
|
||||
ErrSCardNotTransacted ErrorCode = 0x80100016 /* An attempt was made to end a non-existent transaction. */
|
||||
ErrSCardReaderUnavailable ErrorCode = 0x80100017 /* The specified reader is not currently available for use. */
|
||||
ErrSCardShutdown ErrorCode = 0x80100018 /* The operation has been aborted to allow the server application to exit. */
|
||||
ErrSCardPCITooSmall ErrorCode = 0x80100019 /* The PCI Receive buffer was too small. */
|
||||
ErrSCardReaderUnsupported ErrorCode = 0x8010001A /* The reader driver does not meet minimal requirements for support. */
|
||||
ErrSCardDuplicateReader ErrorCode = 0x8010001B /* The reader driver did not produce a unique reader name. */
|
||||
ErrSCardCardUnsupported ErrorCode = 0x8010001C /* The smart card does not meet minimal requirements for support. */
|
||||
ErrScardNoService ErrorCode = 0x8010001D /* The Smart card resource manager is not running. */
|
||||
ErrSCardServiceStopped ErrorCode = 0x8010001E /* The Smart card resource manager has shut down. */
|
||||
ErrSCardUnexpected ErrorCode = 0x8010001F /* An unexpected card error has occurred. */
|
||||
ErrSCardUnsupportedFeature ErrorCode = 0x8010001F /* This smart card does not support the requested feature. */
|
||||
ErrSCardICCInstallation ErrorCode = 0x80100020 /* No primary provider can be found for the smart card. */
|
||||
ErrSCardICCCreateOrder ErrorCode = 0x80100021 /* The requested order of object creation is not supported. */
|
||||
ErrSCardDirNotFound ErrorCode = 0x80100023 /* The identified directory does not exist in the smart card. */
|
||||
ErrSCardFileNotFound ErrorCode = 0x80100024 /* The identified file does not exist in the smart card. */
|
||||
ErrSCardNoDir ErrorCode = 0x80100025 /* The supplied path does not represent a smart card directory. */
|
||||
ErrSCardNoFile ErrorCode = 0x80100026 /* The supplied path does not represent a smart card file. */
|
||||
ErrScardNoAccess ErrorCode = 0x80100027 /* Access is denied to this file. */
|
||||
ErrSCardWriteTooMany ErrorCode = 0x80100028 /* The smart card does not have enough memory to store the information. */
|
||||
ErrSCardBadSeek ErrorCode = 0x80100029 /* There was an error trying to set the smart card file object pointer. */
|
||||
ErrSCardInvalidCHV ErrorCode = 0x8010002A /* The supplied PIN is incorrect. */
|
||||
ErrSCardUnknownResMNG ErrorCode = 0x8010002B /* An unrecognized error code was returned from a layered component. */
|
||||
ErrSCardNoSuchCertificate ErrorCode = 0x8010002C /* The requested certificate does not exist. */
|
||||
ErrSCardCertificateUnavailable ErrorCode = 0x8010002D /* The requested certificate could not be obtained. */
|
||||
ErrSCardNoReadersAvailable ErrorCode = 0x8010002E /* Cannot find a smart card reader. */
|
||||
ErrSCardCommDataLost ErrorCode = 0x8010002F /* A communications error with the smart card has been detected. Retry the operation. */
|
||||
ErrScardNoKeyContainer ErrorCode = 0x80100030 /* The requested key container does not exist on the smart card. */
|
||||
ErrSCardServerTooBusy ErrorCode = 0x80100031 /* The Smart Card Resource Manager is too busy to complete this operation. */
|
||||
ErrSCardUnsupportedCard ErrorCode = 0x80100065 /* The reader cannot communicate with the card, due to ATR string configuration conflicts. */
|
||||
ErrSCardUnresponsiveCard ErrorCode = 0x80100066 /* The smart card is not responding to a reset. */
|
||||
ErrSCardUnpoweredCard ErrorCode = 0x80100067 /* Power has been removed from the smart card, so that further communication is not possible. */
|
||||
ErrSCardResetCard ErrorCode = 0x80100068 /* The smart card has been reset, so any shared state information is invalid. */
|
||||
ErrSCardRemovedCard ErrorCode = 0x80100069 /* The smart card has been removed, so further communication is not possible. */
|
||||
ErrSCardSecurityViolation ErrorCode = 0x8010006A /* Access was denied because of a security violation. */
|
||||
ErrSCardWrongCHV ErrorCode = 0x8010006B /* The card cannot be accessed because the wrong PIN was presented. */
|
||||
ErrSCardCHVBlocked ErrorCode = 0x8010006C /* The card cannot be accessed because the maximum number of PIN entry attempts has been reached. */
|
||||
ErrSCardEOF ErrorCode = 0x8010006D /* The end of the smart card file has been reached. */
|
||||
ErrSCardCancelledByUser ErrorCode = 0x8010006E /* The user pressed "Cancel" on a Smart Card Selection Dialog. */
|
||||
ErrSCardCardNotAuthenticated ErrorCode = 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)
|
||||
}
|
||||
}
|
||||
82
vendor/github.com/gballet/go-libpcsclite/msg.go
generated
vendored
Normal file
82
vendor/github.com/gballet/go-libpcsclite/msg.go
generated
vendored
Normal file
@@ -0,0 +1,82 @@
|
||||
// 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 (
|
||||
"encoding/binary"
|
||||
"net"
|
||||
)
|
||||
|
||||
/**
|
||||
* @brief Wrapper for the MessageSend() function.
|
||||
*
|
||||
* Called by clients to send messages to the server.
|
||||
* The parameters \p command and \p data are set in the \c sharedSegmentMsg
|
||||
* struct in order to be sent.
|
||||
*
|
||||
* @param[in] command Command to be sent.
|
||||
* @param[in] dwClientID Client socket handle.
|
||||
* @param[in] size Size of the message (\p data).
|
||||
* @param[in] data_void Data to be sent.
|
||||
*
|
||||
* @return Same error codes as MessageSend().
|
||||
*/
|
||||
func messageSendWithHeader(command uint32, conn net.Conn, data []byte) error {
|
||||
/* Translate header into bytes */
|
||||
msgData := make([]byte, 8+len(data))
|
||||
binary.LittleEndian.PutUint32(msgData[4:], command)
|
||||
binary.LittleEndian.PutUint32(msgData, uint32(len(data)))
|
||||
|
||||
/* Copy payload */
|
||||
copy(msgData[8:], data)
|
||||
|
||||
_, err := conn.Write(msgData)
|
||||
return err
|
||||
}
|
||||
|
||||
// clientSetupSession prepares a communication channel for the client to talk to the server.
|
||||
// This is called by the application to create a socket for local IPC with the
|
||||
// server. The socket is associated to the file \c PCSCLITE_CSOCK_NAME.
|
||||
/*
|
||||
* @param[out] pdwClientID Client Connection ID.
|
||||
*
|
||||
* @retval 0 Success.
|
||||
* @retval -1 Can not create the socket.
|
||||
* @retval -1 The socket can not open a connection.
|
||||
* @retval -1 Can not set the socket to non-blocking.
|
||||
*/
|
||||
func clientSetupSession(daemonPath string) (net.Conn, error) {
|
||||
path := PCSCDSockName
|
||||
if len(daemonPath) > 0 {
|
||||
path = daemonPath
|
||||
}
|
||||
return net.Dial("unix", path)
|
||||
}
|
||||
402
vendor/github.com/gballet/go-libpcsclite/winscard.go
generated
vendored
Normal file
402
vendor/github.com/gballet/go-libpcsclite/winscard.go
generated
vendored
Normal file
@@ -0,0 +1,402 @@
|
||||
// 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 (
|
||||
"encoding/binary"
|
||||
"fmt"
|
||||
"net"
|
||||
"sync"
|
||||
"unsafe"
|
||||
)
|
||||
|
||||
// Client contains all the information needed to establish
|
||||
// and maintain a connection to the deamon/card.
|
||||
type Client struct {
|
||||
conn net.Conn
|
||||
|
||||
minor uint32
|
||||
major uint32
|
||||
|
||||
ctx uint32
|
||||
|
||||
mutex sync.Mutex
|
||||
|
||||
readerStateDescriptors [MaxReaderStateDescriptors]ReaderState
|
||||
}
|
||||
|
||||
// EstablishContext asks the PCSC daemon to create a context
|
||||
// handle for further communication with connected cards and
|
||||
// readers.
|
||||
func EstablishContext(path string, scope uint32) (*Client, error) {
|
||||
client := &Client{}
|
||||
|
||||
conn, err := clientSetupSession(path)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
client.conn = conn
|
||||
|
||||
payload := make([]byte, 12)
|
||||
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)
|
||||
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() {
|
||||
return nil, fmt.Errorf("invalid response code: expected %d, got %d (%v)", SCardSuccess, code, ErrorCode(code).Error())
|
||||
}
|
||||
client.ctx = binary.LittleEndian.Uint32(response[4:])
|
||||
|
||||
return client, nil
|
||||
}
|
||||
|
||||
// ReleaseContext tells the daemon that the client will no longer
|
||||
// need the context.
|
||||
func (client *Client) ReleaseContext() error {
|
||||
client.mutex.Lock()
|
||||
defer client.mutex.Unlock()
|
||||
|
||||
data := [8]byte{}
|
||||
binary.LittleEndian.PutUint32(data[:], client.ctx)
|
||||
binary.LittleEndian.PutUint32(data[4:], SCardSuccess.Code())
|
||||
err := messageSendWithHeader(SCardReleaseContext, client.conn, data[:])
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
total := 0
|
||||
for total < len(data) {
|
||||
n, err := client.conn.Read(data[total:])
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
total += n
|
||||
}
|
||||
code := binary.LittleEndian.Uint32(data[4:])
|
||||
if code != SCardSuccess.Code() {
|
||||
return fmt.Errorf("invalid return code: %x, %v", code, ErrorCode(code).Error())
|
||||
}
|
||||
|
||||
return nil
|
||||
}
|
||||
|
||||
// Constants related to the reader state structure
|
||||
const (
|
||||
ReaderStateNameLength = 128
|
||||
ReaderStateMaxAtrSizeLength = 33
|
||||
// NOTE: ATR is 32-byte aligned in the C version, which means it's
|
||||
// actually 36 byte long and not 33.
|
||||
ReaderStateDescriptorLength = ReaderStateNameLength + ReaderStateMaxAtrSizeLength + 5*4 + 3
|
||||
|
||||
MaxReaderStateDescriptors = 16
|
||||
)
|
||||
|
||||
// ReaderState represent the state of a single reader, as reported
|
||||
// by the PCSC daemon.
|
||||
type ReaderState struct {
|
||||
Name string /* reader name */
|
||||
eventCounter uint32 /* number of card events */
|
||||
readerState uint32 /* SCARD_* bit field */
|
||||
readerSharing uint32 /* PCSCLITE_SHARING_* sharing status */
|
||||
|
||||
cardAtr [ReaderStateMaxAtrSizeLength]byte /* ATR */
|
||||
cardAtrLength uint32 /* ATR length */
|
||||
cardProtocol uint32 /* SCARD_PROTOCOL_* value */
|
||||
}
|
||||
|
||||
func getReaderState(data []byte) (ReaderState, error) {
|
||||
ret := ReaderState{}
|
||||
if len(data) < ReaderStateDescriptorLength {
|
||||
return ret, fmt.Errorf("could not unmarshall data of length %d < %d", len(data), ReaderStateDescriptorLength)
|
||||
}
|
||||
|
||||
ret.Name = string(data[:ReaderStateNameLength])
|
||||
ret.eventCounter = binary.LittleEndian.Uint32(data[unsafe.Offsetof(ret.eventCounter):])
|
||||
ret.readerState = binary.LittleEndian.Uint32(data[unsafe.Offsetof(ret.readerState):])
|
||||
ret.readerSharing = binary.LittleEndian.Uint32(data[unsafe.Offsetof(ret.readerSharing):])
|
||||
copy(ret.cardAtr[:], data[unsafe.Offsetof(ret.cardAtr):unsafe.Offsetof(ret.cardAtr)+ReaderStateMaxAtrSizeLength])
|
||||
ret.cardAtrLength = binary.LittleEndian.Uint32(data[unsafe.Offsetof(ret.cardAtrLength):])
|
||||
ret.cardProtocol = binary.LittleEndian.Uint32(data[unsafe.Offsetof(ret.cardProtocol):])
|
||||
|
||||
return ret, nil
|
||||
}
|
||||
|
||||
// ListReaders gets the list of readers from the daemon
|
||||
func (client *Client) ListReaders() ([]string, error) {
|
||||
client.mutex.Lock()
|
||||
defer client.mutex.Unlock()
|
||||
|
||||
err := messageSendWithHeader(CommandGetReaderState, client.conn, []byte{})
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
response := make([]byte, ReaderStateDescriptorLength*MaxReaderStateDescriptors)
|
||||
total := 0
|
||||
for total < len(response) {
|
||||
n, err := client.conn.Read(response[total:])
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
total += n
|
||||
}
|
||||
|
||||
var names []string
|
||||
for i := range client.readerStateDescriptors {
|
||||
desc, err := getReaderState(response[i*ReaderStateDescriptorLength:])
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
client.readerStateDescriptors[i] = desc
|
||||
if desc.Name[0] == 0 {
|
||||
break
|
||||
}
|
||||
names = append(names, desc.Name)
|
||||
}
|
||||
|
||||
return names, nil
|
||||
}
|
||||
|
||||
// Offsets into the Connect request/response packet
|
||||
const (
|
||||
SCardConnectReaderNameOffset = 4
|
||||
SCardConnectShareModeOffset = SCardConnectReaderNameOffset + ReaderStateNameLength
|
||||
SCardConnectPreferredProtocolOffset = SCardConnectShareModeOffset + 4
|
||||
SCardConnectReturnValueOffset = SCardConnectPreferredProtocolOffset + 12
|
||||
)
|
||||
|
||||
// Card represents the connection to a card
|
||||
type Card struct {
|
||||
handle uint32
|
||||
activeProto uint32
|
||||
client *Client
|
||||
}
|
||||
|
||||
// Connect asks the daemon to connect to the card
|
||||
func (client *Client) Connect(name string, shareMode uint32, preferredProtocol uint32) (*Card, error) {
|
||||
client.mutex.Lock()
|
||||
defer client.mutex.Unlock()
|
||||
|
||||
request := make([]byte, ReaderStateNameLength+4*6)
|
||||
binary.LittleEndian.PutUint32(request, client.ctx)
|
||||
copy(request[SCardConnectReaderNameOffset:], []byte(name))
|
||||
binary.LittleEndian.PutUint32(request[SCardConnectShareModeOffset:], shareMode)
|
||||
binary.LittleEndian.PutUint32(request[SCardConnectPreferredProtocolOffset:], preferredProtocol)
|
||||
binary.LittleEndian.PutUint32(request[SCardConnectReturnValueOffset:], SCardSuccess.Code())
|
||||
|
||||
err := messageSendWithHeader(SCardConnect, client.conn, request)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
response := make([]byte, ReaderStateNameLength+4*6)
|
||||
total := 0
|
||||
for total < len(response) {
|
||||
n, err := client.conn.Read(response[total:])
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
// fmt.Println("total, n", total, n, response)
|
||||
total += n
|
||||
}
|
||||
code := binary.LittleEndian.Uint32(response[148:])
|
||||
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:])
|
||||
|
||||
return &Card{handle: handle, activeProto: active, client: client}, nil
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief contained in \ref SCARD_TRANSMIT Messages.
|
||||
*
|
||||
* These data are passed throw the field \c sharedSegmentMsg.data.
|
||||
*/
|
||||
//type transmit struct {
|
||||
//hCard uint32
|
||||
//ioSendPciProtocol uint32
|
||||
//ioSendPciLength uint32
|
||||
//cbSendLength uint32
|
||||
//ioRecvPciProtocol uint32
|
||||
//ioRecvPciLength uint32
|
||||
//pcbRecvLength uint32
|
||||
//rv uint32
|
||||
//}
|
||||
|
||||
// SCardIoRequest contains the info needed for performing an IO request
|
||||
type SCardIoRequest struct {
|
||||
proto uint32
|
||||
length uint32
|
||||
}
|
||||
|
||||
const (
|
||||
TransmitRequestLength = 32
|
||||
)
|
||||
|
||||
// Transmit sends request data to a card and returns the response
|
||||
func (card *Card) Transmit(adpu []byte) ([]byte, *SCardIoRequest, error) {
|
||||
card.client.mutex.Lock()
|
||||
defer card.client.mutex.Unlock()
|
||||
|
||||
request := [TransmitRequestLength]byte{}
|
||||
binary.LittleEndian.PutUint32(request[:], card.handle)
|
||||
binary.LittleEndian.PutUint32(request[4:] /*card.activeProto*/, 2)
|
||||
binary.LittleEndian.PutUint32(request[8:], 8)
|
||||
binary.LittleEndian.PutUint32(request[12:], uint32(len(adpu)))
|
||||
binary.LittleEndian.PutUint32(request[16:], 0)
|
||||
binary.LittleEndian.PutUint32(request[20:], 0)
|
||||
binary.LittleEndian.PutUint32(request[24:], 0x10000)
|
||||
binary.LittleEndian.PutUint32(request[28:], SCardSuccess.Code())
|
||||
err := messageSendWithHeader(SCardTransmit, card.client.conn, request[:])
|
||||
if err != nil {
|
||||
return nil, nil, err
|
||||
}
|
||||
// Add the ADPU payload after the transmit descriptor
|
||||
n, err := card.client.conn.Write(adpu)
|
||||
if err != nil {
|
||||
return nil, nil, err
|
||||
}
|
||||
if n != len(adpu) {
|
||||
return nil, nil, fmt.Errorf("invalid number of bytes written: expected %d, got %d", len(adpu), n)
|
||||
}
|
||||
response := [TransmitRequestLength]byte{}
|
||||
total := 0
|
||||
for total < len(response) {
|
||||
n, err = card.client.conn.Read(response[total:])
|
||||
if err != nil {
|
||||
return nil, nil, err
|
||||
}
|
||||
total += n
|
||||
}
|
||||
|
||||
code := binary.LittleEndian.Uint32(response[28:])
|
||||
if code != SCardSuccess.Code() {
|
||||
return nil, nil, fmt.Errorf("invalid return code: %x (%v)", code, ErrorCode(code).Error())
|
||||
}
|
||||
|
||||
// Recover the response data
|
||||
recvProto := binary.LittleEndian.Uint32(response[16:])
|
||||
recvLength := binary.LittleEndian.Uint32(response[20:])
|
||||
recv := &SCardIoRequest{proto: recvProto, length: recvLength}
|
||||
recvLength = binary.LittleEndian.Uint32(response[24:])
|
||||
recvData := make([]byte, recvLength)
|
||||
total = 0
|
||||
for uint32(total) < recvLength {
|
||||
n, err := card.client.conn.Read(recvData[total:])
|
||||
if err != nil {
|
||||
return nil, nil, err
|
||||
}
|
||||
total += n
|
||||
}
|
||||
|
||||
return recvData, recv, nil
|
||||
}
|
||||
|
||||
// Disconnect tells the PCSC daemon that the client is no longer
|
||||
// interested in communicating with the card.
|
||||
func (card *Card) Disconnect(disposition uint32) error {
|
||||
card.client.mutex.Lock()
|
||||
defer card.client.mutex.Unlock()
|
||||
|
||||
data := [12]byte{}
|
||||
binary.LittleEndian.PutUint32(data[:], card.handle)
|
||||
binary.LittleEndian.PutUint32(data[4:], disposition)
|
||||
binary.LittleEndian.PutUint32(data[8:], SCardSuccess.Code())
|
||||
err := messageSendWithHeader(SCardDisConnect, card.client.conn, data[:])
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
total := 0
|
||||
for total < len(data) {
|
||||
n, err := card.client.conn.Read(data[total:])
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
total += n
|
||||
}
|
||||
code := binary.LittleEndian.Uint32(data[8:])
|
||||
if code != SCardSuccess.Code() {
|
||||
return fmt.Errorf("invalid return code: %x (%v)", code, ErrorCode(code).Error())
|
||||
}
|
||||
|
||||
return nil
|
||||
}
|
||||
Reference in New Issue
Block a user