Uploaded image for project: 'JDK'
  1. JDK
  2. JDK-7200271

javax.smartcardio.CardTerminal.isCardPresent always returns false

XMLWordPrintable

      FULL PRODUCT VERSION :
      java version "1.7.0_06-ea"
      Java(TM) SE Runtime Environment (build 1.7.0_06-ea-b08)
      Java HotSpot(TM) 64-Bit Server VM (build 23.0-b21, mixed mode)

      ADDITIONAL OS VERSION INFORMATION :
      Mac OS X only

      EXTRA RELEVANT SYSTEM CONFIGURATION :
      Smart Card reader attached to an OS X system along with a smart card.

      A DESCRIPTION OF THE PROBLEM :
      7195480, but I can't find a way to add more details.

      CardTerminal.isCardPresent() always returns false.



      REGRESSION. Last worked in version 6u31

      STEPS TO FOLLOW TO REPRODUCE THE PROBLEM :
      Run this code on OS X with Oracle Java 7
      TerminalFactory factory = TerminalFactory.getDefault();
      List<CardTerminal> terminals = factory.terminals().list();
      System.out.println("Terminals: " + terminals);
      CardTerminal terminal = terminals.get(0);
      System.out.println(terminal.isCardPresent()); // Always false

      EXPECTED VERSUS ACTUAL BEHAVIOR :
      EXPECTED -
      Returns true when a card is present, false otherwise
      ACTUAL -
      CardTerminal.isCardPresent() always returns false.

      The main issue here is the native layer in Java is reading the wrong part of the struct SCARD_READERSTATE after calling SCardGetStatusChange.

        From Java_sun_security_smartcardio_PCSC_SCardGetStatusChange after the malloc call:

      (gdb) c
      Continuing.

      Breakpoint 3, 0x000000010aa225b2 in Java_sun_security_smartcardio_PCSC_SCardGetStatusChange ()
      3: x/8xw 4300546608
      0x100552230: 0x00554aa0 0x00000001 0x00000000 0x00000000
      0x100552240: 0x00000000 0x00000022 0x00000013 0x0096db3b
                                        ^^^^^^^^ ^^^^^^^^
                                           | +--- Number of bytes in ATR
                                           +--- Event State
      2: /x $rax = 0x0
      1: x/i $rip 0x10aa225b2 <Java_sun_security_smartcardio_PCSC_SCardGetStatusChange+265>: mov %rax,-0x50(%rbp)
      (gdb) set {int}0x100552248 = 0xdeadbeef
      (gdb) display
      3: x/8xw 4300546608
      0x100552230: 0x00554aa0 0x00000001 0x00000000 0x00000000
      0x100552240: 0x00000000 0x00000022 0xdeadbeef 0x0096db3b
                                        ^^^^^^^^ ^^^^^^^^
                                           | +--- Number of bytes in ATR
                                           +--- Event State
      2: /x $rax = 0x0
      1: x/i $rip 0x10aa225b2 <Java_sun_security_smartcardio_PCSC_SCardGetStatusChange+265>: mov %rax,-0x50(%rbp)
      (gdb) c
      Continuing.
      deadbeef <-- Printed from the JVM, the result of directly calling SCardGetStatusChange via reflection
      ^^^^^^^^
         |
         +---- Now in the JVM from a direct reflection call to SCardGetStatusChange
        Program exited normally.
      (gdb)



      REPRODUCIBILITY :
      This bug can be reproduced always.

      ---------- BEGIN SOURCE ----------
      TerminalFactory factory = TerminalFactory.getDefault();
      List<CardTerminal> terminals = factory.terminals().list();
      System.out.println("Terminals: " + terminals);
      CardTerminal terminal = terminals.get(0);
      System.out.println(terminal.isCardPresent()); // Always false
      ---------- END SOURCE ----------

      CUSTOMER SUBMITTED WORKAROUND :
      Since in OS X the method returns the number of bytes in the ATR rather than the event state, the main workaround is to test if the number of ATR bytes is non-zero.

        To do so, code must be written that restricts its execution to Java versions after 1.7 and OS X only. The code must use reflection to directly call SCardGetStatusChange and check the value of the returned ATR size.

            valeriep Valerie Peng
            webbuggrp Webbug Group
            Votes:
            0 Vote for this issue
            Watchers:
            1 Start watching this issue

              Created:
              Updated:
              Resolved:
              Imported:
              Indexed: