Path: blob/master/test/jdk/sun/security/pkcs11/KeyStore/ClientAuth.java
41152 views
/*1* Copyright (c) 2003, 2021, 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.7*8* This code is distributed in the hope that it will be useful, but WITHOUT9* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or10* FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License11* version 2 for more details (a copy is included in the LICENSE file that12* accompanied this code).13*14* You should have received a copy of the GNU General Public License version15* 2 along with this work; if not, write to the Free Software Foundation,16* Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.17*18* Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA19* or visit www.oracle.com if you need additional information or have any20* questions.21*/2223/* @test24* @bug 4938185 710677325* @summary KeyStore support for NSS cert/key databases26* 512 bits RSA key cannot work with SHA384 and SHA51227* @library /test/lib ..28* @run testng/othervm ClientAuth29*/3031import org.testng.annotations.BeforeClass;32import org.testng.annotations.Test;3334import java.io.*;35import java.net.InetAddress;36import java.net.InetSocketAddress;37import java.nio.file.Path;38import java.security.*;39import java.util.Arrays;40import java.util.concurrent.CountDownLatch;41import javax.net.*;42import javax.net.ssl.*;4344public class ClientAuth extends PKCS11Test {4546/*47* =============================================================48* Set the various variables needed for the tests, then49* specify what tests to run on each side.50*/5152private static Provider provider;53private static final String NSS_PWD = "test12";54private static final String JKS_PWD = "passphrase";55private static final String SERVER_KS = "server.keystore";56private static final String TS = "truststore";57private static String p11config;5859private static final Path TEST_DATA_PATH = Path.of(BASE)60.resolve("ClientAuthData");6162private static final String DIR = TEST_DATA_PATH.toString();6364/*65* Should we run the client or server in a separate thread?66* Both sides can throw exceptions, but do you have a preference67* as to which side should be the main thread.68*/69static boolean separateServerThread = false;7071/*72* Is the server ready to serve?73*/74private final CountDownLatch serverReadyLatch = new CountDownLatch(1);7576/*77* Turn on SSL debugging?78*/79static boolean debug = false;8081/*82* If the client or server is doing some kind of object creation83* that the other side depends on, and that thread prematurely84* exits, you may experience a hang. The test harness will85* terminate all hung threads after its timeout has expired,86* currently 3 minutes by default, but you might try to be87* smart about it....88*/8990@BeforeClass91public void setUp() throws Exception {92copyNssCertKeyToClassesDir(TEST_DATA_PATH);93setCommonSystemProps();94System.setProperty("CUSTOM_P11_CONFIG",95TEST_DATA_PATH.resolve("p11-nss.txt").toString());96Security.setProperty("jdk.tls.disabledAlgorithms", "");97Security.setProperty("jdk.certpath.disabledAlgorithms", "");98}99100@Test101public void testClientAuthTLSv1() throws Exception {102String[] args = { "TLSv1" };103runTest(args);104}105106@Test107public void testClientAuthTLSv11() throws Exception {108String[] args = { "TLSv1.1" };109runTest(args);110}111112@Test113public void testClientAuthTLSv12AndCipherSuite() throws Exception {114String[] args = { "TLSv1.2", "TLS_DHE_RSA_WITH_AES_128_CBC_SHA" };115runTest(args);116}117118private void runTest(String[] args) throws Exception {119System.out.println("Running with args: " + Arrays.toString(args));120parseArguments(args);121main(new ClientAuth());122}123124/*125* Define the server side of the test.126*127* If the server prematurely exits, serverReady will be set to true128* to avoid infinite hangs.129*/130void doServerSide() throws Exception {131132SSLContext ctx = SSLContext.getInstance("TLS");133char[] passphrase = JKS_PWD.toCharArray();134135// server gets KeyStore from JKS keystore136KeyStore ks = KeyStore.getInstance("JKS");137ks.load(new FileInputStream(new File(DIR, SERVER_KS)), passphrase);138KeyManagerFactory kmf = KeyManagerFactory.getInstance("SunX509");139kmf.init(ks, passphrase);140141// server gets TrustStore from PKCS#11 token142/*143passphrase = NSS_PWD.toCharArray();144KeyStore ts = KeyStore.getInstance("PKCS11", "SunPKCS11-nss");145ts.load(null, passphrase);146TrustManagerFactory tmf = TrustManagerFactory.getInstance("SunX509");147tmf.init(ts);148*/149150//ctx.init(kmf.getKeyManagers(), tmf.getTrustManagers(), null);151ctx.init(kmf.getKeyManagers(), null, null);152ServerSocketFactory ssf = ctx.getServerSocketFactory();153InetSocketAddress socketAddress =154new InetSocketAddress(InetAddress.getLoopbackAddress(), serverPort);155SSLServerSocket sslServerSocket = (SSLServerSocket) ssf.createServerSocket();156sslServerSocket.bind(socketAddress);157sslServerSocket.setNeedClientAuth(true);158serverPort = sslServerSocket.getLocalPort();159System.out.println("serverPort = " + serverPort);160161/*162* Signal Client, we're ready for his connect.163*/164serverReadyLatch.countDown();165166SSLSocket sslSocket = (SSLSocket) sslServerSocket.accept();167InputStream sslIS = sslSocket.getInputStream();168OutputStream sslOS = sslSocket.getOutputStream();169170sslIS.read();171sslOS.write(85);172sslOS.flush();173174sslSocket.close();175}176177/*178* Define the client side of the test.179*180* If the server prematurely exits, serverReady will be set to true181* to avoid infinite hangs.182*/183void doClientSide() throws Exception {184185/*186* Wait for server to get started.187*/188serverReadyLatch.await();189190SSLContext ctx = SSLContext.getInstance("TLS");191KeyManagerFactory kmf = KeyManagerFactory.getInstance("SunX509");192193// client gets KeyStore from PKCS#11 token,194// and gets TrustStore from JKS KeyStore (using system properties)195char[] passphrase = NSS_PWD.toCharArray();196KeyStore ks = KeyStore.getInstance("PKCS11", "SunPKCS11-nss");197ks.load(null, passphrase);198199kmf = KeyManagerFactory.getInstance("SunX509");200kmf.init(ks, passphrase);201ctx.init(kmf.getKeyManagers(), null, null);202203SSLSocketFactory sslsf = ctx.getSocketFactory();204SSLSocket sslSocket = (SSLSocket)205sslsf.createSocket("localhost", serverPort);206207if (clientProtocol != null) {208sslSocket.setEnabledProtocols(new String[] {clientProtocol});209}210211if (clientCiperSuite != null) {212sslSocket.setEnabledCipherSuites(new String[] {clientCiperSuite});213}214215InputStream sslIS = sslSocket.getInputStream();216OutputStream sslOS = sslSocket.getOutputStream();217218sslOS.write(280);219sslOS.flush();220sslIS.read();221222sslSocket.close();223}224225/*226* =============================================================227* The remainder is just support stuff228*/229230// use any free port by default231volatile int serverPort = 0;232233volatile Exception serverException = null;234volatile Exception clientException = null;235236private static String clientProtocol = null;237private static String clientCiperSuite = null;238239private static void parseArguments(String[] args) {240if (args.length > 0) {241clientProtocol = args[0];242}243244if (args.length > 1) {245clientCiperSuite = args[1];246}247}248249public void main(Provider p) throws Exception {250// SSL RSA client auth currently needs an RSA cipher251// (cf. NONEwithRSA hack), which is currently not available in252// open builds.253try {254javax.crypto.Cipher.getInstance("RSA/ECB/PKCS1Padding", p);255} catch (GeneralSecurityException e) {256System.out.println("Not supported by provider, skipping");257return;258}259260this.provider = p;261262System.setProperty("javax.net.ssl.trustStore",263new File(DIR, TS).toString());264System.setProperty("javax.net.ssl.trustStoreType", "JKS");265System.setProperty("javax.net.ssl.trustStoreProvider", "SUN");266System.setProperty("javax.net.ssl.trustStorePassword", JKS_PWD);267268// perform Security.addProvider of P11 provider269Security.addProvider(getSunPKCS11(System.getProperty("CUSTOM_P11_CONFIG")));270271if (debug) {272System.setProperty("javax.net.debug", "all");273}274275/*276* Start the tests.277*/278go();279}280281Thread clientThread = null;282Thread serverThread = null;283284/*285* Fork off the other side, then do your work.286*/287private void go() throws Exception {288try {289if (separateServerThread) {290startServer(true);291startClient(false);292} else {293startClient(true);294startServer(false);295}296} catch (Exception e) {297//swallow for now. Show later298}299300/*301* Wait for other side to close down.302*/303if (separateServerThread) {304serverThread.join();305} else {306clientThread.join();307}308309/*310* When we get here, the test is pretty much over.311* Which side threw the error?312*/313Exception local;314Exception remote;315String whichRemote;316317if (separateServerThread) {318remote = serverException;319local = clientException;320whichRemote = "server";321} else {322remote = clientException;323local = serverException;324whichRemote = "client";325}326327/*328* If both failed, return the curthread's exception, but also329* print the remote side Exception330*/331if ((local != null) && (remote != null)) {332System.out.println(whichRemote + " also threw:");333remote.printStackTrace();334System.out.println();335throw local;336}337338if (remote != null) {339throw remote;340}341342if (local != null) {343throw local;344}345}346347void startServer (boolean newThread) {348if (newThread) {349serverThread = new Thread(() -> {350try {351doServerSide();352} catch (Exception e) {353/*354* Our server thread just died.355*356* Release the client, if not active already...357*/358System.err.println("Server died...");359serverReadyLatch.countDown();360serverException = e;361}362});363serverThread.start();364} else {365try {366doServerSide();367} catch (Exception e) {368serverException = e;369} finally {370serverReadyLatch.countDown();371}372}373}374375void startClient (boolean newThread) {376if (newThread) {377clientThread = new Thread(() -> {378try {379doClientSide();380} catch (Exception e) {381/*382* Our client thread just died.383*/384System.err.println("Client died...");385clientException = e;386}387});388clientThread.start();389} else {390try {391doClientSide();392} catch (Exception e) {393clientException = e;394}395}396}397}398399400