public synchronized List<CardTerminal> list(State state) throws CardException {
   // System.out.println("list");
   if (state == null) {
     throw new NullPointerException();
   }
   try {
     String[] readerNames = SCardListReaders(contextId);
     List<CardTerminal> list = new ArrayList<CardTerminal>(readerNames.length);
     if (stateMap == null) {
       // If waitForChange() has never been called, treat event
       // queries as status queries.
       if (state == CARD_INSERTION) {
         state = CARD_PRESENT;
       } else if (state == CARD_REMOVAL) {
         state = CARD_ABSENT;
       }
     }
     for (String readerName : readerNames) {
       CardTerminal terminal = implGetTerminal(readerName);
       ReaderState readerState;
       switch (state) {
         case ALL:
           list.add(terminal);
           break;
         case CARD_PRESENT:
           if (terminal.isCardPresent()) {
             list.add(terminal);
           }
           break;
         case CARD_ABSENT:
           if (terminal.isCardPresent() == false) {
             list.add(terminal);
           }
           break;
         case CARD_INSERTION:
           readerState = stateMap.get(readerName);
           if ((readerState != null) && readerState.isInsertion()) {
             list.add(terminal);
           }
           break;
         case CARD_REMOVAL:
           readerState = stateMap.get(readerName);
           if ((readerState != null) && readerState.isRemoval()) {
             list.add(terminal);
           }
           break;
         default:
           throw new CardException("Unknown state: " + state);
       }
     }
     return Collections.unmodifiableList(list);
   } catch (PCSCException e) {
     throw new CardException("list() failed", e);
   }
 }
Exemple #2
0
  public void ConnectToSmartCard() {
    try {
      TerminalFactory factory = TerminalFactory.getDefault();
      List<CardTerminal> terminals = factory.terminals().list();
      System.out.println("Terminals: " + terminals);
      // get the first terminal
      // CardTerminals.State.
      CardTerminal terminal = terminals.get(0);

      if (terminal.isCardPresent()) {
        JOptionPane.showMessageDialog(null, "Card is Present");
        this.terminal = terminal;
      } else {
        JOptionPane.showMessageDialog(null, "Card is absent.Connnect it in 5 secs\nWaiting...");
        terminal.waitForCardPresent(5000);
        JOptionPane.showMessageDialog(null, "Time is Up!\nBye!!!");
        return;
      }
      // establish a connection with the card
      Card card = terminal.connect("*");
      this.card1 = card;
    } catch (CardException ce) {

    }
  }
Exemple #3
0
  private synchronized boolean activateTerminal() {
    Interfacer.getLogger().log("ACTIVATE TERMINAL");
    // select which terminal to use
    if (_cardTerminal != null) _activeCardTerminal = _cardTerminal;
    else {
      while (_activeCardTerminal == null) {
        try {
          for (CardTerminal cardTerminalLoop : _cardTerminals) {
            if (cardTerminalLoop.isCardPresent()
                && !cardTerminalLoop.getName().toUpperCase().contains("EMULATOR")) {
              _activeCardTerminal = cardTerminalLoop;
              break;
            }
          }
          if (_activeCardTerminal == null) {
            Interfacer.getLogger().log("INSERT CARD (s)");
            Thread.sleep(1000);
          }
        } catch (Exception e) {
        }
      }
    }
    Interfacer.getLogger().log("ACTIVE TERMINAL: " + _activeCardTerminal.getName());
    try {
      // wait for a card to be put in the terminal
      while (!_activeCardTerminal.isCardPresent()
          && !_activeCardTerminal.getName().toUpperCase().contains("EMULATOR")) {
        Interfacer.getLogger().log("INSERT CARD (s)");
        Thread.sleep(1000);
      }

      if (_activePassportService == null) {
        _activeCardService = new TerminalCardService(_activeCardTerminal);
        _activePassportService = new PassportService(_activeCardService);
        _activePassportService.open();
      }
      Interfacer.getLogger().log("CARD INSERTED AT: " + _activeCardTerminal.getName());
      return true;
    } catch (Exception e) {
      e.printStackTrace();
    }

    // something went wrong if we reached this point, clear the selected terminal
    Interfacer.getLogger().log("NO TERMINAL COULD BE ACTIVATED");
    return false;
  }
Exemple #4
0
  /**
   * Function to connect to the MSC
   *
   * @throws TokenException
   */
  public void connect() throws TokenException {
    int i, j;

    try {
      /*
       * Get all available terminals..
       */
      TerminalFactory factory = TerminalFactory.getDefault();
      List<CardTerminal> terminals = factory.terminals().list();
      if (terminals.isEmpty()) {
        throw new TokenException("No terminals found");
      }

      /*
       * Select appropriate terminal
       */
      CardTerminal terminal = null;
      for (i = 0; i < terminals.size(); i++) {
        /*
         * Try the known terminal names the msc-driver uses..
         */
        for (j = 0; j < TERMINAL_NAMES.length; j++) {
          if (terminals.get(i).getName().startsWith(TERMINAL_NAMES[j])) {
            terminal = terminals.get(i);
            break;
          }
        }
      }
      if (terminal == null || !terminal.isCardPresent()) {
        throw new TokenException("No G&D MSC found in terminal(s)");
      }

      /*
       * Establish a connection with the myCard
       */
      myCard = terminal.connect("T=1");
      myChannel = myCard.getBasicChannel();

      /*
       * Of the several AIDs in distribution, try to select one that
       * actually works.. ;)
       */
      boolean appSelected = false;
      for (i = 0; i < APPLET_IDS.length; i++) {
        if (appSelected = selectApplet(APPLET_IDS[i])) {
          break;
        }
      }
      if (!appSelected) {
        throw new TokenException("Could not select Applet");
      }
    } catch (TokenException e) {
      throw e;
    } catch (Exception e) {
      throw new TokenException("Some exception occured: " + e.toString());
    }
  }
Exemple #5
0
 public synchronized String getStatus() {
   if (activateTerminal()) {
     try {
       if (_activeCardTerminal.isCardPresent()) return "Card present";
       else return "No card present";
     } catch (Exception e) {
       return e.toString();
     }
   } else return "Not connected";
 }
Exemple #6
0
    @Override
    public List<TerminalState> start() throws SCIOException {
      logger.trace("Entering start().");
      if (pendingEvents != null) {
        throw new IllegalStateException(
            "Trying to initialize already initialized watcher instance.");
      }
      pendingEvents = new LinkedList<>();
      terminals = new HashSet<>();
      cardPresent = new HashSet<>();

      try {
        // call wait for change and directly afterwards get current list of cards
        // with a bit of luck no change has happened in between and the list is coherent
        own.terminals.waitForChange(1);
        List<CardTerminal> javaTerminals = own.terminals.list();
        ArrayList<TerminalState> result = new ArrayList<>(javaTerminals.size());
        // fill sets according to state of the terminals
        logger.debug("Detecting initial terminal status.");
        for (CardTerminal next : javaTerminals) {
          String name = next.getName();
          boolean cardInserted = next.isCardPresent();
          logger.debug("Terminal='{}' cardPresent={}", name, cardInserted);
          terminals.add(name);
          if (cardInserted) {
            cardPresent.add(name);
            result.add(new TerminalState(name, true));
          } else {
            result.add(new TerminalState(name, false));
          }
        }
        // return list of our terminals
        logger.trace("Leaving start() with {} states.", result.size());
        return Collections.unmodifiableList(result);
      } catch (CardException ex) {
        if (getCode(ex) == SCIOErrorCode.SCARD_E_NO_READERS_AVAILABLE) {
          logger.debug("No reader available exception.");
          return Collections.emptyList();
        } else if (getCode(ex) == SCIOErrorCode.SCARD_E_NO_SERVICE) {
          logger.debug("No service available exception, reloading PCSC and returning empty list.");
          parent.reloadFactory();
          own.loadTerminals();
          return Collections.emptyList();
        }
        String msg = "Failed to retrieve status from the PCSC system.";
        logger.error(msg, ex);
        throw new SCIOException(msg, getCode(ex), ex);
      } catch (IllegalStateException ex) {
        logger.debug("No reader available exception.");
        return Collections.emptyList();
      }
    }
Exemple #7
0
  public boolean IsCardPresent() {
    boolean Ispresent = false;
    if (card1 != null && terminal != null) {
      try {
        if (terminal.isCardPresent()) {
          Ispresent = true;
        } else {
          Ispresent = false;
        }
      } catch (CardException ce) {

      }

    } else {
      // JOptionPane.showMessageDialog(null,"SmartCard Initialization Problem\nBye!!!");
    }
    return Ispresent;
  }
 /**
  * openChannel
  *
  * @param applet
  * @return Channel
  * @throws Exception
  */
 private CardChannel openChannel(AppletModel applet) throws Exception {
   if (channel != null) {
     try {
       channel.close();
     } catch (Exception e) {
       //
     }
     channel = null;
   }
   if (card != null) {
     try {
       card.disconnect(true);
     } catch (Exception e) {
       //
     }
     card = null;
   }
   TerminalFactory factory = TerminalFactory.getDefault();
   CardTerminals cardterminals = factory.terminals();
   try {
     List<CardTerminal> terminals = cardterminals.list();
     System.out.println("Terminals: " + terminals);
     for (CardTerminal terminal : terminals) {
       terminal.waitForCardPresent(1000);
       if (terminal.isCardPresent()) {
         System.out.println(terminal.getName() + ": Card present!");
         card = terminal.connect("*");
         channel = card.getBasicChannel();
         return channel;
       }
     }
     throw new WolfException(MSG_READER_TIME_OUT);
   } catch (Exception e) {
     throw e;
   }
 }
Exemple #9
0
  private static void work(CardTerminal reader, OptionSet args) throws CardException {
    if (!reader.isCardPresent()) {
      System.out.println("No card in " + reader.getName());
      return;
    }

    FileOutputStream o = null;
    if (args.has(OPT_DUMP)) {
      try {
        o = new FileOutputStream((File) args.valueOf(OPT_DUMP));
      } catch (FileNotFoundException e) {
        System.err.println("Can not dump to " + args.valueOf(OPT_DUMP));
      }
    }
    reader = LoggingCardTerminal.getInstance(reader, o);
    // This allows to override the protocol for RemoteTerminal as well.
    final String protocol;
    if (args.has(OPT_T0)) {
      protocol = "T=0";
    } else if (args.has(OPT_T1)) {
      protocol = "T=1";
    } else {
      protocol = "*";
    }
    if (args.has(CMD_APDU)) {

      Card c = null;
      try {
        c = reader.connect(protocol);

        if (args.has(CMD_APDU)) {
          for (Object s : args.valuesOf(CMD_APDU)) {
            CommandAPDU a = new CommandAPDU(HexUtils.stringToBin((String) s));
            ResponseAPDU r = c.getBasicChannel().transmit(a);
            if (args.has(OPT_ERROR) && r.getSW() != 0x9000) {
              System.out.println(
                  "Card returned " + String.format("%04X", r.getSW()) + ", exiting!");
              return;
            }
          }
        }
      } catch (CardException e) {
        if (TerminalManager.getExceptionMessage(e) != null) {
          System.out.println("PC/SC failure: " + TerminalManager.getExceptionMessage(e));
        } else {
          throw e;
        }
      } finally {
        if (c != null) {
          c.disconnect(true);
        }
      }
    } else if (args.has(OPT_CONNECT)) {
      String remote = (String) args.valueOf(OPT_CONNECT);
      JSONMessagePipe transport = null;

      try {
        if (remote.startsWith("http://") || remote.startsWith("https://")) {
          if (args.has(OPT_PINNED)) {
            transport =
                HTTPTransport.open(
                    new URL(remote), certFromPEM(((File) args.valueOf(OPT_PINNED)).getPath()));
          } else {
            transport = HTTPTransport.open(new URL(remote), null);
          }
        } else {
          transport = SocketTransport.connect(string2socket(remote), null);
        }

        // Connect the transport and the terminal
        CmdlineRemoteTerminal c = new CmdlineRemoteTerminal(transport, reader);
        c.forceProtocol(protocol);
        // Run
        c.run();
      } catch (IOException e) {
        System.err.println("Communication error: " + e.getMessage());
      } finally {
        if (transport != null) transport.close();
      }
    }
  }
Exemple #10
0
  public static void main(String[] argv) throws Exception {
    OptionSet args = parseOptions(argv);

    if (args.has(OPT_VERBOSE)) {
      verbose = true;
      // Set up slf4j simple in a way that pleases us
      System.setProperty("org.slf4j.simpleLogger.defaultLogLevel", "debug");
      System.setProperty("org.slf4j.simpleLogger.showThreadName", "true");
      System.setProperty("org.slf4j.simpleLogger.showShortLogName", "true");
      System.setProperty("org.slf4j.simpleLogger.levelInBrackets", "true");
    } else {
      System.setProperty("org.slf4j.simpleLogger.defaultLogLevel", "warn");
    }

    if (args.has(OPT_VERSION)) {
      String version = "apdu4j " + getVersion(SCTool.class);
      // Append host information
      version += "\nRunning on " + System.getProperty("os.name");
      version += " " + System.getProperty("os.version");
      version += " " + System.getProperty("os.arch");
      version += ", Java " + System.getProperty("java.version");
      version += " by " + System.getProperty("java.vendor");
      System.out.println(version);
    }
    if (args.has(OPT_TEST_SERVER)) {
      // TODO: have the possibility to run SocketServer as well?
      RemoteTerminalServer srv = new RemoteTerminalServer(TestServer.class);
      srv.start(string2socket((String) args.valueOf(OPT_TEST_SERVER)));
      System.console().readLine("Press enter to stop\n");
      srv.stop(1);
      System.exit(0);
    }

    // List TerminalFactory providers
    if (args.has(OPT_PROVIDERS)) {
      Provider providers[] = Security.getProviders("TerminalFactory.PC/SC");
      if (providers != null) {
        System.out.println("Existing TerminalFactory providers:");
        for (Provider p : providers) {
          System.out.println(p.getName());
        }
      }
    }

    // Fix properties on non-windows platforms
    TerminalManager.fixPlatformPaths();

    // Only applies to SunPCSC
    if (args.has(OPT_NO_GET_RESPONSE)) {
      System.setProperty("sun.security.smartcardio.t0GetResponse", "false");
      System.setProperty("sun.security.smartcardio.t1GetResponse", "false");
    }

    // Override PC/SC library path
    if (args.has(OPT_LIB)) {
      System.setProperty("sun.security.smartcardio.library", (String) args.valueOf(OPT_LIB));
    }

    TerminalFactory tf = null;
    CardTerminals terminals = null;

    try {
      // Get a terminal factory
      if (args.has(OPT_PROVIDER)) {
        String pn = (String) args.valueOf(OPT_PROVIDER);
        String pt = (String) args.valueOf(OPT_PROVIDER_TYPE);
        tf = loadFactory(pn, pt);
      } else if (args.has(OPT_SUN)) {
        tf = loadFactory(SUN_CLASS, null);
      } else if (args.has(OPT_JNA)) {
        tf = loadFactory(JNA_CLASS, null);
      } else {
        tf = TerminalFactory.getDefault();
      }

      if (verbose) {
        System.out.println(
            "# Using " + tf.getProvider().getClass().getCanonicalName() + " - " + tf.getProvider());
        if (System.getProperty(TerminalManager.lib_prop) != null) {
          System.out.println(
              "# " + TerminalManager.lib_prop + "=" + System.getProperty(TerminalManager.lib_prop));
        }
      }
      // Get all terminals
      terminals = tf.terminals();
    } catch (Exception e) {
      // XXX: we catch generic Exception here to avoid importing JNA.
      // Try to get a meaningful message
      String msg = TerminalManager.getExceptionMessage(e);
      if (msg == null) msg = e.getMessage();
      System.out.println("No readers: " + msg);
      System.exit(1);
    }

    // Terminals to work on
    List<CardTerminal> do_readers = new ArrayList<CardTerminal>();

    try {
      // List Terminals
      if (args.has(CMD_LIST)) {
        List<CardTerminal> terms = terminals.list();
        if (verbose) {
          System.out.println(
              "# Found " + terms.size() + " terminal" + (terms.size() == 1 ? "" : "s"));
        }
        if (terms.size() == 0) {
          System.err.println("No readers found");
          System.exit(1);
        }
        for (CardTerminal t : terms) {
          String vmd = " ";
          try (PinPadTerminal pp = new PinPadTerminal(t)) {
            pp.probe();
            // Verify, Modify, Display
            if (verbose) {
              vmd += "[";
              vmd += pp.canVerify() ? "V" : " ";
              vmd += pp.canModify() ? "M" : " ";
              vmd += pp.hasDisplay() ? "D" : " ";
              vmd += "] ";
            }
          } catch (CardException e) {
            if (verbose) {
              System.err.println("Could not probe PinPad: " + e.getMessage());
            }
          }

          System.out.println((t.isCardPresent() ? "[*]" : "[ ]") + vmd + t.getName());

          if (args.has(OPT_VERBOSE) && t.isCardPresent()) {
            Card c = t.connect("DIRECT");
            String atr = HexUtils.encodeHexString(c.getATR().getBytes()).toUpperCase();
            c.disconnect(false);
            System.out.println("          " + atr);
            if (args.has(OPT_WEB)) {
              String url = "http://smartcard-atr.appspot.com/parse?ATR=" + atr;
              if (Desktop.isDesktopSupported()) {
                Desktop.getDesktop().browse(new URI(url + "&from=apdu4j"));
              } else {
                System.out.println("          " + url);
              }
            }
          }
        }
      }

      // Select terminals to work on
      if (args.has(OPT_READER)) {
        String reader = (String) args.valueOf(OPT_READER);
        CardTerminal t = terminals.getTerminal(reader);
        if (t == null) {
          System.err.println("Reader \"" + reader + "\" not found.");
          System.exit(1);
        }
        do_readers = Arrays.asList(t);
      } else {
        do_readers = terminals.list(State.CARD_PRESENT);
        if (do_readers.size() > 1 && !args.hasArgument(OPT_ALL)) {
          System.err.println("More than one reader with a card found.");
          System.err.println("Run with --" + OPT_ALL + " to work with all found cards");
          System.exit(1);
        } else if (do_readers.size() == 0 && !args.has(CMD_LIST)) {
          // But if there is a single reader, wait for a card insertion
          List<CardTerminal> empty = terminals.list(State.CARD_ABSENT);
          if (empty.size() == 1 && args.has(OPT_WAIT)) {
            CardTerminal rdr = empty.get(0);
            System.out.println("Please enter a card into " + rdr.getName());
            if (!empty.get(0).waitForCardPresent(30000)) {
              System.out.println("Timeout.");
            } else {
              do_readers = Arrays.asList(rdr);
            }
          } else {
            System.err.println("No reader with a card found!");
            System.exit(1);
          }
        }
      }

    } catch (CardException e) {
      System.out.println("Could not list readers: " + TerminalManager.getExceptionMessage(e));
      e.printStackTrace();
    }

    for (CardTerminal t : do_readers) {
      work(t, args);
    }
  }
Exemple #11
0
    @Override
    public StateChangeEvent waitForChange(long timeout) throws SCIOException {
      logger.trace("Entering waitForChange().");
      if (pendingEvents == null) {
        throw new IllegalStateException("Calling wait on uninitialized watcher instance.");
      }

      // try to return any present events first
      StateChangeEvent nextEvent = pendingEvents.poll();
      if (nextEvent != null) {
        logger.trace("Leaving waitForChange() with queued event.");
        return nextEvent;
      } else {
        Pair<Boolean, Boolean> waitResult;
        try {
          waitResult = internalWait(timeout);
        } catch (CardException ex) {
          String msg = "Error while waiting for a state change in the terminals.";
          logger.error(msg, ex);
          throw new SCIOException(msg, getCode(ex), ex);
        }
        boolean changed = waitResult.p1;
        boolean error = waitResult.p2;

        if (!changed) {
          logger.trace("Leaving waitForChange() with no event.");
          return new StateChangeEvent();
        } else {
          // something has changed, retrieve actual terminals from the system and see what has
          // changed
          Collection<String> newTerminals = new HashSet<>();
          Collection<String> newCardPresent = new HashSet<>();
          // only ask for terminals if there is no error
          if (!error) {
            try {
              List<CardTerminal> newStates = own.terminals.list();
              for (CardTerminal next : newStates) {
                String name = next.getName();
                newTerminals.add(name);
                if (next.isCardPresent()) {
                  newCardPresent.add(name);
                }
              }
            } catch (CardException ex) {
              String msg = "Failed to retrieve status of the observed terminals.";
              logger.error(msg, ex);
              throw new SCIOException(msg, getCode(ex), ex);
            }
          }

          // calculate what has actually happened
          // removed cards
          Collection<String> cardRemoved = subtract(cardPresent, newCardPresent);
          Collection<StateChangeEvent> crEvents = createEvents(EventType.CARD_REMOVED, cardRemoved);
          // removed terminals
          Collection<String> termRemoved = subtract(terminals, newTerminals);
          Collection<StateChangeEvent> trEvents =
              createEvents(EventType.TERMINAL_REMOVED, termRemoved);
          // added terminals
          Collection<String> termAdded = subtract(newTerminals, terminals);
          Collection<StateChangeEvent> taEvents = createEvents(EventType.TERMINAL_ADDED, termAdded);
          // added cards
          Collection<String> cardAdded = subtract(newCardPresent, cardPresent);
          Collection<StateChangeEvent> caEvents = createEvents(EventType.CARD_INSERTED, cardAdded);

          // update internal status with the calculated state
          terminals = newTerminals;
          cardPresent = newCardPresent;
          pendingEvents.addAll(crEvents);
          pendingEvents.addAll(trEvents);
          pendingEvents.addAll(taEvents);
          pendingEvents.addAll(caEvents);
          // use remove so we get an exception when no event has been recorded
          // this would mean our algorithm is corrupt
          logger.trace("Leaving waitForChange() with fresh event.");
          return pendingEvents.remove();
        }
      }
    }