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); } }
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) { } }
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; }
/** * 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()); } }
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"; }
@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(); } }
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; } }
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(); } } }
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); } }
@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(); } } }