OS X Yosemite bug: SCARD_E_PROTO_MISMATCH not returned
This is part of the series: "OS X Yosemite and smart cards: known bugs".
SCARD_E_PROTO_MISMATCH not returned by SCardConnect()
In case of card communication protocol not supported, SCardConnect() returns the errorSCARD_E_NOT_TRANSACTED
on Yosemite but the error code is SCARD_E_PROTO_MISMATCH
on Mavericks (and also on pcsc-lite on GNU/Linux).This is a regression from Mavericks. I guess the same problem is also present with SCardReconnect().
SCARD_E_NOT_TRANSACTED
should not be the error code for any error. SCARD_E_PROTO_MISMATCH
is the correct error code to return in this case.See also
Apple bug report #19384251 "PC/SC: SCARD_E_PROTO_MISMATCH not returned by SCardConnect()". Closed by Apple, 9th January 2015, as a duplicated of #18689292.Sample code
The sample code usesSCardConnect(.., SCARD_PROTOCOL_T1, ..)
to force the use of T=1. If you insert a T=0 only card you will get an error code from SCardConnect()
.#include <stdio.h> #include <stdlib.h> #include <string.h> #ifdef __APPLE__ #include <PCSC/winscard.h> #include <PCSC/wintypes.h> #else #include <winscard.h> #endif int main(int argc, const char * argv[]) { SCARDCONTEXT hContext; LPSTR mszReaders; DWORD err = SCardEstablishContext(SCARD_SCOPE_SYSTEM, NULL, NULL, &hContext); if (err != SCARD_S_SUCCESS) { printf("ScardEstablishedContext : %08x\n",err); return -1; } DWORD cchReaders = 0; err = SCardListReaders(hContext, "SCard$AllReaders", NULL, &cchReaders); if (err != 0) { printf("ScardListReaders : %08x\n",err); return -1; } mszReaders = calloc(cchReaders, sizeof(char)); if (!mszReaders) { printf("calloc\n"); return -1; } err = SCardListReaders(hContext,"SCard$AllReaders", mszReaders, &cchReaders); if (err != SCARD_S_SUCCESS) { printf("ScardListReaders : %08x\n",err); return -1; } printf("Reader : %s\n", mszReaders); SCARDHANDLE hCard; DWORD dwActiveProtocol; err = SCardConnect(hContext, mszReaders, SCARD_SHARE_SHARED, SCARD_PROTOCOL_T1, &hCard, &dwActiveProtocol); if (err != SCARD_S_SUCCESS) { printf("SCardConnect: 0x%08x\n",err); return -1; } SCardDisconnect(hCard, SCARD_LEAVE_CARD); SCardReleaseContext(hContext); return 0; }
Result (on Yosemite)
$ CFLAGS="-framework PCSC" make main cc -framework PCSC main.c -o main
$ ./main Reader : Gemalto PC Twin Reader SCardConnect: 0x80100016
0x80100016 is SCARD_E_NOT_TRANSACTED.
Expected result (on Mavericks)
$ CFLAGS="-framework PCSC" make main cc -framework PCSC main.c -o main
$ ./main Reader : Gemplus GemPC Twin 00 00 SCardConnect: 0x8010000f
0x8010000f is SCARD_E_PROTO_MISMATCH.
Known workaround
You should expect the errorSCARD_E_NOT_TRANSACTED
instead of SCARD_E_PROTO_MISMATCH
on Yosemite.On Yosemite it is no more possible to decide if
SCARD_E_NOT_TRANSACTED
is returned because the requested protocol is not supported or because another error has occurred.