Closed bowb closed 3 years ago
I re-compiled virtualsmardcard with debugging on and the buffer overflow detected went away. I am getting different behavior with debugging flags turned on with virtualsmartcard.
./configure --sysconfdir=/etc CFLAGS="-g -O0"
make
sudo make install
list readers on the host now returns a reader
# Detected readers (pcsc)
Nr. Card Features Name
0 Yes Virtual PCD 00 00
1 No Virtual PCD 00 01
The virtual card in the container is using jcard with a FIPS201 applet and when in the container it acts like I expect it to. pcsc_scan on the container
Scanning present readers...
0: Virtual PCD 00 00
1: Virtual PCD 00 01
Tue Mar 30 15:59:53 2021
Reader 0: Virtual PCD 00 00
Card state: Card inserted,
ATR: 3B DF 96 00 81 B1 FE 45 1F 83 80 73 CC 91 CB F9 A0 00 00 03 08 00 00 10 00 79
ATR: 3B DF 96 00 81 B1 FE 45 1F 83 80 73 CC 91 CB F9 A0 00 00 03 08 00 00 10 00 79
+ TS = 3B --> Direct Convention
+ T0 = DF, Y(1): 1101, K: 15 (historical bytes)
TA(1) = 96 --> Fi=512, Di=32, 16 cycles/ETU
250000 bits/s at 4 MHz, fMax for Fi = 5 MHz => 312500 bits/s
TC(1) = 00 --> Extra guard time: 0
TD(1) = 81 --> Y(i+1) = 1000, Protocol T = 1
-----
TD(2) = B1 --> Y(i+1) = 1011, Protocol T = 1
-----
TA(3) = FE --> IFSC: 254
TB(3) = 45 --> Block Waiting Integer: 4 - Character Waiting Integer: 5
TD(3) = 1F --> Y(i+1) = 0001, Protocol T = 15 - Global interface bytes following
-----
TA(4) = 83 --> Clock stop: state H - Class accepted by the card: (3G) A 5V B 3V
+ Historical bytes: 80 73 CC 91 CB F9 A0 00 00 03 08 00 00 10 00
Category indicator byte: 80 (compact TLV data object)
Tag: 7, len: 3 (card capabilities)
Selection methods: CC
- DF selection by full DF name
- DF selection by partial DF name
- Implicit DF selection
- Short EF identifier supported
Data coding byte: 91
- EF of TLV structure supported
- Behaviour of write functions: one-time write
- Value 'FF' for the first byte of BER-TLV tag fields: valid
- Data unit in quartets: 2
Command chaining, length fields and logical channels: CB
- Command chaining
- Extended Lc and Le fields
- Logical channel number assignment: by the interface device
- Maximum number of logical channels: 4
Tag: F, len: 9 (application identifier)
Application identifier: A0 00 00 03 08 00 00 10 00
+ TCK = 79 (correct checksum)
Possibly identified card (using /usr/share/pcsc/smartcard_list.txt):
3B DF 96 00 81 B1 FE 45 1F 83 80 73 CC 91 CB F9 A0 00 00 03 08 00 00 10 00 79
Test PIV Cards available for sale from NIST
http://csrc.nist.gov/groups/SNS/piv/testcards.html
On the host
Scanning present readers...
0: Virtual PCD 00 00
1: Virtual PCD 00 01
Tue Mar 30 10:01:26 2021
Reader 0: Virtual PCD 00 00
Card state: Card inserted,
ATR: 3B 80 80 01 01
ATR: 3B 80 80 01 01
+ TS = 3B --> Direct Convention
+ T0 = 80, Y(1): 1000, K: 0 (historical bytes)
TD(1) = 80 --> Y(i+1) = 1000, Protocol T = 0
-----
TD(2) = 01 --> Y(i+1) = 0000, Protocol T = 1
-----
+ Historical bytes:
+ TCK = 01 (correct checksum)
Possibly identified card (using /home/test/.cache/smartcard_list.txt):
3B 80 80 01 01
ISO 14443 Type B without historical bytes
Electronic Passport
Spanish passport (2012)
Canadian Passport
Venez_Prox
Other commands that work in the container do not work on the host. For example running the following on the container will prompt for the pin and dump the data but on the host it does not work.
pkcs11-tool -r -y data --login --application-id 2.16.840.1.101.3.7.2.96.48
Is this something that can be done?
I'd be curious to know the source of your exception.
For your ATR, use pcsc-relay --vicc-atr=3BDF960081B1FE451F838073CC91CBF9A0000003080000100079 ...
Setting --vicc-atr=3BDF960081B1FE451F838073CC91CBF9A0000003080000100079
worked. I don't see this option in the documentation, but I do see it when I run pcsc-relay --help
the *** buffer overflow detected ***: pcscd terminated
I think is coming from libc compile time flags for security and stack protection. https://wiki.ubuntu.com/ToolChain/CompilerFlags Any suggestions on how I could help you track this down?
Thanks for the help on the atr.
you can run pcscd in valgrind, for example with debug symbols enabled. this should track and print memory violations:
sudo valgrind /usr/sbin/pcscd --foreground --debug --apdu
I compiled with ./configure --sysconfdir=/etc CFLAGS="-g -O1"
sudo valgrind /usr/sbin/pcscd -c /home/bowb/card_test/vpcd.local -afd
==67469== Memcheck, a memory error detector
==67469== Copyright (C) 2002-2017, and GNU GPL'd, by Julian Seward et al.
==67469== Using Valgrind-3.13.0 and LibVEX; rerun with -h for copyright info
==67469== Command: /usr/sbin/pcscd -c /home/bowb/card_test/vpcd.local -afd
==67469==
00000000 debuglog.c:289:DebugLogSetLevel() debug level=debug
00044683 configfile.l:361:DBGetReaderList() Parsing conf file: /home/bowb/card_test/vpcd.local
00015583 configfile.l:211:evaluatetoken() Add reader: Virtual PCD
00009584 readerfactory.c:1075:RFInitializeReader() Attempting startup of Virtual PCD 00 00 using /usr/local/lib/pcsc/drivers/serial/libifdvpcd.so
00014901 readerfactory.c:950:RFBindFunctions() Loading IFD Handler 3.0
00063981 ifd-vpcd.c:124:IFDHCreateChannel() Connected to virtual ICC on localhost port 35966
00000892 ifd-vpcd.c:290:IFDHGetCapabilities() unknown tag 4019
00000440 readerfactory.c:391:RFAddReader() Using the pcscd polling thread
00036789 readerfactory.c:524:RFAddReader() Driver is slot thread safe
00000444 readerfactory.c:1075:RFInitializeReader() Attempting startup of Virtual PCD 00 01 using /usr/local/lib/pcsc/drivers/serial/libifdvpcd.so
00002597 readerfactory.c:864:RFLoadReader() Reusing already loaded driver for /usr/local/lib/pcsc/drivers/serial/libifdvpcd.so
00000179 readerfactory.c:950:RFBindFunctions() Loading IFD Handler 3.0
00002168 ifd-vpcd.c:124:IFDHCreateChannel() Connected to virtual ICC on localhost port 35967
00000375 ifd-vpcd.c:290:IFDHGetCapabilities() unknown tag 4019
00000356 readerfactory.c:558:RFAddReader() Using the pcscd polling thread
00030594 pcscdaemon.c:662:main() pcsc-lite 1.8.23 daemon ready.
*** buffer overflow detected ***: /usr/sbin/pcscd terminated
==67469==
==67469== Process terminating with default action of signal 6 (SIGABRT)
==67469== at 0x5741FB7: raise (raise.c:51)
==67469== by 0x5743920: abort (abort.c:79)
==67469== by 0x578C966: __libc_message (libc_fatal.c:181)
==67469== by 0x5837B8E: __fortify_fail_abort (fortify_fail.c:33)
==67469== by 0x5837BB0: __fortify_fail (fortify_fail.c:44)
==67469== by 0x583589F: __chk_fail (chk_fail.c:28)
==67469== by 0x5837A99: __fdelt_chk (fdelt_chk.c:25)
==67469== by 0x7272144: waitforclient (vpcd.c:186)
==67469== by 0x7272641: vicc_connect (vpcd.c:369)
==67469== by 0x72726D9: vicc_present (vpcd.c:390)
==67469== by 0x7271F75: IFDHICCPresence (ifd-vpcd.c:428)
==67469== by 0x10F492: ??? (in /usr/sbin/pcscd)
==67469==
==67469== HEAP SUMMARY:
==67469== in use at exit: 142,745 bytes in 1,314 blocks
==67469== total heap usage: 4,099 allocs, 2,785 frees, 569,601 bytes allocated
==67469==
==67469== LEAK SUMMARY:
==67469== definitely lost: 116 bytes in 1 blocks
==67469== indirectly lost: 0 bytes in 0 blocks
==67469== possibly lost: 917 bytes in 4 blocks
==67469== still reachable: 141,712 bytes in 1,309 blocks
==67469== suppressed: 0 bytes in 0 blocks
==67469== Rerun with --leak-check=full to see details of leaked memory
==67469==
==67469== For counts of detected and suppressed errors, rerun with: -v
==67469== ERROR SUMMARY: 0 errors from 0 contexts (suppressed: 0 from 0)
Aborted
My system has too many open sockets for FD_SET to work in vpcd.c The recommendation is to move to poll.
I changed it to the following, but I don't know if this will work on windows.
SOCKET waitforclient(SOCKET server, long secs, long usecs)
{
struct pollfd pfd;
struct sockaddr_in client_sockaddr;
socklen_t client_socklen = sizeof client_sockaddr;
int timeout;
pfd.fd = server;
timeout = (secs * 1000000 + usecs / 1000);
if (poll(&pfd, 1, timeout) == -1)
return INVALID_SOCKET;
if(pfd.revents & POLLIN)
return accept(server, (struct sockaddr *) &client_sockaddr,
&client_socklen);
return INVALID_SOCKET;
}
Possible patch? I really don't know if the FD_SET on windows suffers from the same behavior on linux.
diff --git a/virtualsmartcard/src/vpcd/vpcd.c b/virtualsmartcard/src/vpcd/vpcd.c
index ef7bb85..da4a861 100644
--- a/virtualsmartcard/src/vpcd/vpcd.c
+++ b/virtualsmartcard/src/vpcd/vpcd.c
@@ -38,6 +38,7 @@ typedef WORD uint16_t;
#else
#include <arpa/inet.h>
#include <netdb.h>
+#include <poll.h>
#include <stdint.h>
#include <sys/socket.h>
#include <sys/time.h>
@@ -171,21 +172,18 @@ err:
SOCKET waitforclient(SOCKET server, long secs, long usecs)
{
- fd_set rfds;
+
struct sockaddr_in client_sockaddr;
socklen_t client_socklen = sizeof client_sockaddr;
+
+#if _WIN32
+ fd_set rfds;
struct timeval tv;
- FD_ZERO(&rfds);
-#if _WIN32
- /* work around clumsy define of FD_SET in winsock2.h */
#pragma warning(disable:4127)
FD_SET(server, &rfds);
-#pragma warning(default:4127)
-#else
- FD_SET(server, &rfds);
-#endif
-
+#pragma warning(default:4127)
+
tv.tv_sec = secs;
tv.tv_usec = usecs;
@@ -193,6 +191,21 @@ SOCKET waitforclient(SOCKET server, long secs, long usecs)
return INVALID_SOCKET;
if (FD_ISSET(server, &rfds))
+ /* work around clumsy define of FD_SET in winsock2.h */
+
+#else
+ int timeout;
+ struct pollfd pfd;
+
+ pfd.fd = server;
+
+ timeout = (secs * 1000000 + usecs / 1000);
+
+ if (poll(&pfd, 1, timeout) == -1)
+ return INVALID_SOCKET;
+
+ if(pfd.revents & POLLIN)
+#endif
return accept(server, (struct sockaddr *) &client_sockaddr,
&client_socklen);
in terms of portability, poll()
should be good enough. Would you mind creating a pull request?
Version: did a build from master.
System: Ubuntu 18.04
Is it possible to pcsc-relay an already virtual smart card?
I am on ubuntu 18 and I have docker container that I have setup using pcsd and vcpd with a virtual javacard. I am trying to relay it so the host can use the card.
On the docker container
running it on a different port gives the following but I don't know if this a valid configuration
On the host the config file and pcscd run:
If this can be done how would the host be able to use the Virtual Smartcard running on the container?