8046343: (smartcardio) CardTerminal.connect('direct') does not work on MacOSX
Reviewed-by: mullan, valeriep
--- a/jdk/src/share/classes/sun/security/smartcardio/CardImpl.java Thu Aug 07 15:07:33 2014 +0400
+++ b/jdk/src/share/classes/sun/security/smartcardio/CardImpl.java Thu Aug 07 15:32:23 2014 +0400
@@ -1,5 +1,5 @@
/*
- * Copyright (c) 2005, 2010, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 2005, 2014, Oracle and/or its affiliates. All rights reserved.
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
*
* This code is free software; you can redistribute it and/or modify it
@@ -26,9 +26,9 @@
package sun.security.smartcardio;
import java.nio.ByteBuffer;
-
+import java.security.AccessController;
+import java.security.PrivilegedAction;
import javax.smartcardio.*;
-
import static sun.security.smartcardio.PCSC.*;
/**
@@ -62,6 +62,15 @@
// thread holding exclusive access to the card, or null
private volatile Thread exclusiveThread;
+ // used for platform specific logic
+ private static final boolean isWindows;
+
+ static {
+ final String osName = AccessController.doPrivileged(
+ (PrivilegedAction<String>) () -> System.getProperty("os.name"));
+ isWindows = osName.startsWith("Windows");
+ }
+
CardImpl(TerminalImpl terminal, String protocol) throws PCSCException {
this.terminal = terminal;
int sharingMode = SCARD_SHARE_SHARED;
@@ -74,7 +83,12 @@
connectProtocol = SCARD_PROTOCOL_T1;
} else if (protocol.equalsIgnoreCase("direct")) {
// testing
- connectProtocol = 0;
+
+ // MSDN states that the preferred protocol can be zero, but doesn't
+ // specify whether other values are allowed.
+ // pcsc-lite implementation expects the preferred protocol to be non zero.
+ connectProtocol = isWindows ? 0 : SCARD_PROTOCOL_RAW;
+
sharingMode = SCARD_SHARE_DIRECT;
} else {
throw new IllegalArgumentException("Unsupported protocol " + protocol);
--- a/jdk/test/sun/security/smartcardio/TestAll.java Thu Aug 07 15:07:33 2014 +0400
+++ b/jdk/test/sun/security/smartcardio/TestAll.java Thu Aug 07 15:32:23 2014 +0400
@@ -40,6 +40,7 @@
TestMultiplePresent.class,
TestPresent.class,
TestTransmit.class,
+ TestDirect.class,
};
public static void main(String[] args) throws Exception {
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/jdk/test/sun/security/smartcardio/TestDirect.java Thu Aug 07 15:32:23 2014 +0400
@@ -0,0 +1,48 @@
+/*
+ * Copyright (c) 2014, Oracle and/or its affiliates. All rights reserved.
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * This code is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License version 2 only, as
+ * published by the Free Software Foundation.
+ *
+ * This code is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
+ * version 2 for more details (a copy is included in the LICENSE file that
+ * accompanied this code).
+ *
+ * You should have received a copy of the GNU General Public License version
+ * 2 along with this work; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
+ *
+ * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
+ * or visit www.oracle.com if you need additional information or have any
+ * questions.
+ */
+
+/**
+ * @test
+ * @bug 8046343
+ * @summary Make sure that direct protocol is available
+ * @run main/manual TestDirect
+ */
+
+// This test requires special hardware.
+
+import javax.smartcardio.Card;
+import javax.smartcardio.CardTerminal;
+import javax.smartcardio.CardTerminals;
+import javax.smartcardio.TerminalFactory;
+
+public class TestDirect {
+ public static void main(String[] args) throws Exception {
+ TerminalFactory terminalFactory = TerminalFactory.getDefault();
+ CardTerminals cardTerminals = terminalFactory.terminals();
+ CardTerminal cardTerminal = cardTerminals.list().get(0);
+ Card card = cardTerminal.connect("DIRECT");
+ card.disconnect(true);
+
+ System.out.println("OK.");
+ }
+}