Page 1 of 1

C++ and JavaCard Virtual Reader

Posted: Thu Oct 13, 2016 7:55 pm
by eclessiastes
Hello
I made a javacard script that display hello world when i send 80 00 00 00 apdu command. I'm trying to communicate from my c++ program but i always get 90 00 return for any apdu i send. here is my script
:

Code: Select all

package helloworld;

import javacard.framework.*;

public class helloworld extends Applet
{
private static final byte[] javacard = {(byte)'J',(byte)'a',(byte)'v',(byte)'a',(byte)' ',(byte)'C',(byte)'a',(byte)'r',(byte)'d',(byte)'!',};
private static final byte JC_CLA = (byte)0x80;
private static final byte JC_INS = (byte)0x00;

public static void install(byte[] bArray, short bOffset, byte bLength)
{
   new helloworld().register(bArray, (short) (bOffset + 1), bArray[bOffset]);
}
   public void process(APDU apdu)
   {
      if (selectingApplet())
      {
         return;
      }

      byte[] buf = apdu.getBuffer();
      
      
      byte CLA = (byte) (buf[ISO7816.OFFSET_CLA] & 0xFF);
        byte INS = (byte) (buf[ISO7816.OFFSET_INS] & 0xFF);

    if (CLA != JC_CLA)
    {
        ISOException.throwIt(ISO7816.SW_CLA_NOT_SUPPORTED);
    }


      switch (buf[ISO7816.OFFSET_INS])
      {
      case (byte)0x00: OutPut(apdu); break;
      default: ISOException.throwIt(ISO7816.SW_INS_NOT_SUPPORTED); break;
      }
   }
   
   private void OutPut( APDU apdu)
    {
    byte[] buffer = apdu.getBuffer();
    short length = (short) javacard.length;
    Util.arrayCopyNonAtomic(javacard, (short)0, buffer, (short)0, (short)  length);
    apdu.setOutgoingAndSend((short)0, length);
     }

}

This is ludovic c++ sample

Code: Select all

#ifdef WIN32
#undef UNICODE
#endif

#include <stdio.h>
#include <stdlib.h>

#ifdef __APPLE__
#include <PCSC/winscard.h>
#include <PCSC/wintypes.h>
#else
#include <winscard.h>
#endif
#pragma comment(lib, "Winscard.lib")
#ifdef WIN32
static char *pcsc_stringify_error(LONG rv)
{
   static char out[20];
   sprintf_s(out, sizeof(out), "0x%08X", rv);

   return out;
}
#endif

#define CHECK(f, rv) \
 if (SCARD_S_SUCCESS != rv) \
 { \
  printf(f ": %s\n", pcsc_stringify_error(rv)); \
  return -1; \
 }

int main(void)
{
   LONG rv;

   SCARDCONTEXT hContext;
   LPTSTR mszReaders;
   SCARDHANDLE hCard;
   DWORD dwReaders, dwActiveProtocol, dwRecvLength;

   SCARD_IO_REQUEST pioSendPci;
   BYTE pbRecvBuffer[258];
   BYTE cmd1[] = { 0x00, 0xA4, 0x04, 0x00, 0x00, 0x12, 0x34, 0x56, 0x78, 0x90 };
   BYTE cmd2[] = { 0x80, 0x00, 0x00, 0x00, 0x00,0x00 };

   unsigned int i;

   rv = SCardEstablishContext(SCARD_SCOPE_SYSTEM, NULL, NULL, &hContext);
   CHECK("SCardEstablishContext", rv)

#ifdef SCARD_AUTOALLOCATE
      dwReaders = SCARD_AUTOALLOCATE;

   rv = SCardListReaders(hContext, NULL, (LPTSTR)&mszReaders, &dwReaders);
   CHECK("SCardListReaders", rv)
#else
      rv = SCardListReaders(hContext, NULL, NULL, &dwReaders);
   CHECK("SCardListReaders", rv)

      mszReaders = calloc(dwReaders, sizeof(char));
   rv = SCardListReaders(hContext, NULL, mszReaders, &dwReaders);
   CHECK("SCardListReaders", rv)
#endif
      printf("reader name: %s\n", mszReaders);

   rv = SCardConnect(hContext, mszReaders, SCARD_SHARE_SHARED,
      SCARD_PROTOCOL_T0 | SCARD_PROTOCOL_T1, &hCard, &dwActiveProtocol);
   CHECK("SCardConnect", rv)

      switch (dwActiveProtocol)
      {
      case SCARD_PROTOCOL_T0:
         pioSendPci = *SCARD_PCI_T0;
         break;

      case SCARD_PROTOCOL_T1:
         pioSendPci = *SCARD_PCI_T1;
         break;
      }
   dwRecvLength = sizeof(pbRecvBuffer);
   rv = SCardTransmit(hCard, &pioSendPci, cmd1, sizeof(cmd1),
      NULL, pbRecvBuffer, &dwRecvLength);
   CHECK("SCardTransmit", rv)

      printf("response: ");
   for (i = 0; i<dwRecvLength; i++)
      printf("%02X ", pbRecvBuffer[i]);
   printf("\n");

   dwRecvLength = sizeof(pbRecvBuffer);
   rv = SCardTransmit(hCard, &pioSendPci, cmd2, sizeof(cmd2),
      NULL, pbRecvBuffer, &dwRecvLength);
   CHECK("SCardTransmit", rv)

      printf("response: ");
   for (i = 0; i<dwRecvLength; i++)
      printf("%02X ", pbRecvBuffer[i]);
   printf("\n");

   rv = SCardDisconnect(hCard, SCARD_LEAVE_CARD);
   CHECK("SCardDisconnect", rv)

#ifdef SCARD_AUTOALLOCATE
      rv = SCardFreeMemory(hContext, mszReaders);
   CHECK("SCardFreeMemory", rv)

#else
      free(mszReaders);
#endif

   rv = SCardReleaseContext(hContext);

   CHECK("SCardReleaseContext", rv)

      system("PAUSE");
      return 0;
}


For some reason i always get success 90 00 whatever command i send. Can anyone help please ?

Re: C++ and JavaCard Virtual Reader

Posted: Thu Oct 13, 2016 11:10 pm
by UNKNwYSHSA
1 Command SELECT is incorrect, Lc is not 0x00, shall be 0x05:

Code: Select all

   BYTE cmd1[] = { 0x00, 0xA4, 0x04, 0x00, 0x00, 0x12, 0x34, 0x56, 0x78, 0x90 };
=>

Code: Select all

   BYTE cmd1[] = { 0x00, 0xA4, 0x04, 0x00, 0x05, 0x12, 0x34, 0x56, 0x78, 0x90 };
2 Use following code to list readers and connect to the reader user selected:

Code: Select all

    // Parse reader names from mszReaders;
    char* ppcReaderNames[100] = { 0 };
    int iReadersCount = 0;
    char* pcReaderName = mszReaders;
    while (true) {
        if (*pcReaderName == '\0') {
            break;
        }
        ppcReaderNames[iReadersCount] = pcReaderName;
        ++iReadersCount;
        pcReaderName += strlen(pcReaderName) + 1;
    }
   
    // List all readers;
    printf("Readers name:\n");
    for (int i = 0; i < iReadersCount; ++i) {
        printf("%d - %s\n", i, ppcReaderNames[i]);
    }
   
    // User select one reader;
    printf("Please select one reader to communicate: ");
    int iReaderIndex = 0;
    do {
        char caTemp[0x100];
        gets_s(caTemp, sizeof(caTemp));
        iReaderIndex = atoi(caTemp);
    } while (iReaderIndex >= iReadersCount);

    // Connect to the reader user selected;
    rv = SCardConnect(hContext, ppcReaderNames[iReaderIndex], SCARD_SHARE_SHARED,
        SCARD_PROTOCOL_T0 | SCARD_PROTOCOL_T1, &hCard, &dwActiveProtocol);
    CHECK("SCardConnect", rv)

3 Here's my running result:

Code: Select all

Readers name:
0 - Infineon virtual PC/SC Reader 2
1 - JAVACOS Virtual Contact Reader 0
2 - JAVACOS Virtual Contactless Reader 1
Please select one reader to communicate: 1
response: 90 00
response: 4A 61 76 61 20 43 61 72 64 21 90 00
Press any key to continue . . .