Path: blob/aarch64-shenandoah-jdk8u272-b10/jdk/src/share/classes/sun/security/smartcardio/TerminalImpl.java
38829 views
/*1* Copyright (c) 2005, 2016, Oracle and/or its affiliates. All rights reserved.2* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.3*4* This code is free software; you can redistribute it and/or modify it5* under the terms of the GNU General Public License version 2 only, as6* published by the Free Software Foundation. Oracle designates this7* particular file as subject to the "Classpath" exception as provided8* by Oracle in the LICENSE file that accompanied this code.9*10* This code is distributed in the hope that it will be useful, but WITHOUT11* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or12* FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License13* version 2 for more details (a copy is included in the LICENSE file that14* accompanied this code).15*16* You should have received a copy of the GNU General Public License version17* 2 along with this work; if not, write to the Free Software Foundation,18* Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.19*20* Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA21* or visit www.oracle.com if you need additional information or have any22* questions.23*/2425package sun.security.smartcardio;2627import java.util.*;2829import javax.smartcardio.*;3031import static sun.security.smartcardio.PCSC.*;3233/**34* CardTerminal implementation.35*36* @since 1.637* @author Andreas Sterbenz38*/39final class TerminalImpl extends CardTerminal {4041// native SCARDCONTEXT42final long contextId;4344// the name of this terminal (native PC/SC name)45final String name;4647private CardImpl card;4849TerminalImpl(long contextId, String name) {50this.contextId = contextId;51this.name = name;52}5354public String getName() {55return name;56}5758public synchronized Card connect(String protocol) throws CardException {59SecurityManager sm = System.getSecurityManager();60if (sm != null) {61sm.checkPermission(new CardPermission(name, "connect"));62}63if (card != null) {64if (card.isValid()) {65String cardProto = card.getProtocol();66if (protocol.equals("*") || protocol.equalsIgnoreCase(cardProto)) {67return card;68} else {69throw new CardException("Cannot connect using " + protocol70+ ", connection already established using " + cardProto);71}72} else {73card = null;74}75}76try {77card = new CardImpl(this, protocol);78return card;79} catch (PCSCException e) {80if (e.code == SCARD_W_REMOVED_CARD || e.code == SCARD_E_NO_SMARTCARD) {81throw new CardNotPresentException("No card present", e);82} else {83throw new CardException("connect() failed", e);84}85}86}8788public boolean isCardPresent() throws CardException {89try {90int[] status = SCardGetStatusChange(contextId, 0,91new int[] {SCARD_STATE_UNAWARE}, new String[] {name});92return (status[0] & SCARD_STATE_PRESENT) != 0;93} catch (PCSCException e) {94throw new CardException("isCardPresent() failed", e);95}96}9798private boolean waitForCard(boolean wantPresent, long timeout) throws CardException {99if (timeout < 0) {100throw new IllegalArgumentException("timeout must not be negative");101}102if (timeout == 0) {103timeout = TIMEOUT_INFINITE;104}105int[] status = new int[] {SCARD_STATE_UNAWARE};106String[] readers = new String[] {name};107try {108// check if card status already matches109status = SCardGetStatusChange(contextId, 0, status, readers);110boolean present = (status[0] & SCARD_STATE_PRESENT) != 0;111if (wantPresent == present) {112return true;113}114// no match, wait (until timeout expires)115long end = System.currentTimeMillis() + timeout;116while (wantPresent != present && timeout != 0) {117// set remaining timeout118if (timeout != TIMEOUT_INFINITE) {119timeout = Math.max(end - System.currentTimeMillis(), 0l);120}121status = SCardGetStatusChange(contextId, timeout, status, readers);122present = (status[0] & SCARD_STATE_PRESENT) != 0;123}124return wantPresent == present;125} catch (PCSCException e) {126if (e.code == SCARD_E_TIMEOUT) {127return false;128} else {129throw new CardException("waitForCard() failed", e);130}131}132}133134public boolean waitForCardPresent(long timeout) throws CardException {135return waitForCard(true, timeout);136}137138public boolean waitForCardAbsent(long timeout) throws CardException {139return waitForCard(false, timeout);140}141142public String toString() {143return "PC/SC terminal " + name;144}145}146147148