Book a Demo!
CoCalc Logo Icon
StoreFeaturesDocsShareSupportNewsAboutPoliciesSign UpSign In
PojavLauncherTeam
GitHub Repository: PojavLauncherTeam/openjdk-multiarch-jdk8u
Path: blob/aarch64-shenandoah-jdk8u272-b10/jdk/src/share/classes/sun/security/smartcardio/TerminalImpl.java
38829 views
1
/*
2
* Copyright (c) 2005, 2016, Oracle and/or its affiliates. All rights reserved.
3
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
4
*
5
* This code is free software; you can redistribute it and/or modify it
6
* under the terms of the GNU General Public License version 2 only, as
7
* published by the Free Software Foundation. Oracle designates this
8
* particular file as subject to the "Classpath" exception as provided
9
* by Oracle in the LICENSE file that accompanied this code.
10
*
11
* This code is distributed in the hope that it will be useful, but WITHOUT
12
* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
13
* FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
14
* version 2 for more details (a copy is included in the LICENSE file that
15
* accompanied this code).
16
*
17
* You should have received a copy of the GNU General Public License version
18
* 2 along with this work; if not, write to the Free Software Foundation,
19
* Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
20
*
21
* Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
22
* or visit www.oracle.com if you need additional information or have any
23
* questions.
24
*/
25
26
package sun.security.smartcardio;
27
28
import java.util.*;
29
30
import javax.smartcardio.*;
31
32
import static sun.security.smartcardio.PCSC.*;
33
34
/**
35
* CardTerminal implementation.
36
*
37
* @since 1.6
38
* @author Andreas Sterbenz
39
*/
40
final class TerminalImpl extends CardTerminal {
41
42
// native SCARDCONTEXT
43
final long contextId;
44
45
// the name of this terminal (native PC/SC name)
46
final String name;
47
48
private CardImpl card;
49
50
TerminalImpl(long contextId, String name) {
51
this.contextId = contextId;
52
this.name = name;
53
}
54
55
public String getName() {
56
return name;
57
}
58
59
public synchronized Card connect(String protocol) throws CardException {
60
SecurityManager sm = System.getSecurityManager();
61
if (sm != null) {
62
sm.checkPermission(new CardPermission(name, "connect"));
63
}
64
if (card != null) {
65
if (card.isValid()) {
66
String cardProto = card.getProtocol();
67
if (protocol.equals("*") || protocol.equalsIgnoreCase(cardProto)) {
68
return card;
69
} else {
70
throw new CardException("Cannot connect using " + protocol
71
+ ", connection already established using " + cardProto);
72
}
73
} else {
74
card = null;
75
}
76
}
77
try {
78
card = new CardImpl(this, protocol);
79
return card;
80
} catch (PCSCException e) {
81
if (e.code == SCARD_W_REMOVED_CARD || e.code == SCARD_E_NO_SMARTCARD) {
82
throw new CardNotPresentException("No card present", e);
83
} else {
84
throw new CardException("connect() failed", e);
85
}
86
}
87
}
88
89
public boolean isCardPresent() throws CardException {
90
try {
91
int[] status = SCardGetStatusChange(contextId, 0,
92
new int[] {SCARD_STATE_UNAWARE}, new String[] {name});
93
return (status[0] & SCARD_STATE_PRESENT) != 0;
94
} catch (PCSCException e) {
95
throw new CardException("isCardPresent() failed", e);
96
}
97
}
98
99
private boolean waitForCard(boolean wantPresent, long timeout) throws CardException {
100
if (timeout < 0) {
101
throw new IllegalArgumentException("timeout must not be negative");
102
}
103
if (timeout == 0) {
104
timeout = TIMEOUT_INFINITE;
105
}
106
int[] status = new int[] {SCARD_STATE_UNAWARE};
107
String[] readers = new String[] {name};
108
try {
109
// check if card status already matches
110
status = SCardGetStatusChange(contextId, 0, status, readers);
111
boolean present = (status[0] & SCARD_STATE_PRESENT) != 0;
112
if (wantPresent == present) {
113
return true;
114
}
115
// no match, wait (until timeout expires)
116
long end = System.currentTimeMillis() + timeout;
117
while (wantPresent != present && timeout != 0) {
118
// set remaining timeout
119
if (timeout != TIMEOUT_INFINITE) {
120
timeout = Math.max(end - System.currentTimeMillis(), 0l);
121
}
122
status = SCardGetStatusChange(contextId, timeout, status, readers);
123
present = (status[0] & SCARD_STATE_PRESENT) != 0;
124
}
125
return wantPresent == present;
126
} catch (PCSCException e) {
127
if (e.code == SCARD_E_TIMEOUT) {
128
return false;
129
} else {
130
throw new CardException("waitForCard() failed", e);
131
}
132
}
133
}
134
135
public boolean waitForCardPresent(long timeout) throws CardException {
136
return waitForCard(true, timeout);
137
}
138
139
public boolean waitForCardAbsent(long timeout) throws CardException {
140
return waitForCard(false, timeout);
141
}
142
143
public String toString() {
144
return "PC/SC terminal " + name;
145
}
146
}
147
148