Path: blob/aarch64-shenandoah-jdk8u272-b10/jdk/test/sun/security/mscapi/ShortRSAKeyWithinTLS.java
38840 views
/*1* Copyright (c) 2012, 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.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*/2223import java.io.*;24import java.net.*;25import java.util.*;26import java.security.*;27import java.security.cert.*;28import javax.net.*;29import javax.net.ssl.*;3031import sun.security.util.KeyUtil;3233public class ShortRSAKeyWithinTLS {3435/*36* =============================================================37* Set the various variables needed for the tests, then38* specify what tests to run on each side.39*/4041/*42* Should we run the client or server in a separate thread?43* Both sides can throw exceptions, but do you have a preference44* as to which side should be the main thread.45*/46static boolean separateServerThread = false;4748/*49* Is the server ready to serve?50*/51volatile static boolean serverReady = false;5253/*54* Turn on SSL debugging?55*/56static boolean debug = false;5758/*59* If the client or server is doing some kind of object creation60* that the other side depends on, and that thread prematurely61* exits, you may experience a hang. The test harness will62* terminate all hung threads after its timeout has expired,63* currently 3 minutes by default, but you might try to be64* smart about it....65*/6667/*68* Define the server side of the test.69*70* If the server prematurely exits, serverReady will be set to true71* to avoid infinite hangs.72*/73void doServerSide() throws Exception {7475// load the key store76serverKS = KeyStore.getInstance("Windows-MY", "SunMSCAPI");77serverKS.load(null, null);78System.out.println("Loaded keystore: Windows-MY");7980// check key size81checkKeySize(serverKS);8283// initialize the SSLContext84KeyManagerFactory kmf = KeyManagerFactory.getInstance("SunX509");85kmf.init(serverKS, null);8687TrustManagerFactory tmf = TrustManagerFactory.getInstance("SunX509");88tmf.init(serverKS);89TrustManager[] tms = tmf.getTrustManagers();90if (tms == null || tms.length == 0) {91throw new Exception("unexpected trust manager implementation");92} else {93if (!(tms[0] instanceof X509TrustManager)) {94throw new Exception("unexpected trust manager" +95" implementation: " +96tms[0].getClass().getCanonicalName());97}98}99serverTM = new MyExtendedX509TM((X509TrustManager)tms[0]);100tms = new TrustManager[] {serverTM};101102SSLContext ctx = SSLContext.getInstance("TLS");103ctx.init(kmf.getKeyManagers(), tms, null);104105ServerSocketFactory ssf = ctx.getServerSocketFactory();106SSLServerSocket sslServerSocket = (SSLServerSocket)107ssf.createServerSocket(serverPort);108sslServerSocket.setNeedClientAuth(true);109serverPort = sslServerSocket.getLocalPort();110System.out.println("serverPort = " + serverPort);111112/*113* Signal Client, we're ready for his connect.114*/115serverReady = true;116117SSLSocket sslSocket = (SSLSocket) sslServerSocket.accept();118InputStream sslIS = sslSocket.getInputStream();119OutputStream sslOS = sslSocket.getOutputStream();120121sslIS.read();122sslOS.write(85);123sslOS.flush();124125sslSocket.close();126}127128/*129* Define the client side of the test.130*131* If the server prematurely exits, serverReady will be set to true132* to avoid infinite hangs.133*/134void doClientSide() throws Exception {135136/*137* Wait for server to get started.138*/139while (!serverReady) {140Thread.sleep(50);141}142143// load the key store144KeyStore ks = KeyStore.getInstance("Windows-MY", "SunMSCAPI");145ks.load(null, null);146System.out.println("Loaded keystore: Windows-MY");147148// initialize the SSLContext149KeyManagerFactory kmf = KeyManagerFactory.getInstance("SunX509");150kmf.init(ks, null);151152TrustManagerFactory tmf = TrustManagerFactory.getInstance("SunX509");153tmf.init(ks);154155SSLContext ctx = SSLContext.getInstance("TLS");156ctx.init(kmf.getKeyManagers(), tmf.getTrustManagers(), null);157158SSLSocketFactory sslsf = ctx.getSocketFactory();159SSLSocket sslSocket = (SSLSocket)160sslsf.createSocket("localhost", serverPort);161162if (clientProtocol != null) {163sslSocket.setEnabledProtocols(new String[] {clientProtocol});164}165166if (clientCiperSuite != null) {167sslSocket.setEnabledCipherSuites(new String[] {clientCiperSuite});168}169170InputStream sslIS = sslSocket.getInputStream();171OutputStream sslOS = sslSocket.getOutputStream();172173sslOS.write(280);174sslOS.flush();175sslIS.read();176177sslSocket.close();178}179180private void checkKeySize(KeyStore ks) throws Exception {181PrivateKey privateKey = null;182PublicKey publicKey = null;183184if (ks.containsAlias(keyAlias)) {185System.out.println("Loaded entry: " + keyAlias);186privateKey = (PrivateKey)ks.getKey(keyAlias, null);187publicKey = (PublicKey)ks.getCertificate(keyAlias).getPublicKey();188189int privateKeySize = KeyUtil.getKeySize(privateKey);190if (privateKeySize != keySize) {191throw new Exception("Expected key size is " + keySize +192", but the private key size is " + privateKeySize);193}194195int publicKeySize = KeyUtil.getKeySize(publicKey);196if (publicKeySize != keySize) {197throw new Exception("Expected key size is " + keySize +198", but the public key size is " + publicKeySize);199}200}201}202203/*204* =============================================================205* The remainder is just support stuff206*/207208// use any free port by default209volatile int serverPort = 0;210211volatile Exception serverException = null;212volatile Exception clientException = null;213214private static String keyAlias;215private static int keySize;216private static String clientProtocol = null;217private static String clientCiperSuite = null;218219private static void parseArguments(String[] args) {220keyAlias = args[0];221keySize = Integer.parseInt(args[1]);222223if (args.length > 2) {224clientProtocol = args[2];225}226227if (args.length > 3) {228clientCiperSuite = args[3];229}230}231232public static void main(String[] args) throws Exception {233if (debug) {234System.setProperty("javax.net.debug", "all");235}236237// Get the customized arguments.238parseArguments(args);239240new ShortRSAKeyWithinTLS();241}242243Thread clientThread = null;244Thread serverThread = null;245KeyStore serverKS;246MyExtendedX509TM serverTM;247248/*249* Primary constructor, used to drive remainder of the test.250*251* Fork off the other side, then do your work.252*/253ShortRSAKeyWithinTLS() throws Exception {254try {255if (separateServerThread) {256startServer(true);257startClient(false);258} else {259startClient(true);260startServer(false);261}262} catch (Exception e) {263// swallow for now. Show later264}265266/*267* Wait for other side to close down.268*/269if (separateServerThread) {270serverThread.join();271} else {272clientThread.join();273}274275/*276* When we get here, the test is pretty much over.277* Which side threw the error?278*/279Exception local;280Exception remote;281String whichRemote;282283if (separateServerThread) {284remote = serverException;285local = clientException;286whichRemote = "server";287} else {288remote = clientException;289local = serverException;290whichRemote = "client";291}292293/*294* If both failed, return the curthread's exception, but also295* print the remote side Exception296*/297if ((local != null) && (remote != null)) {298System.out.println(whichRemote + " also threw:");299remote.printStackTrace();300System.out.println();301throw local;302}303304if (remote != null) {305throw remote;306}307308if (local != null) {309throw local;310}311}312313void startServer(boolean newThread) throws Exception {314if (newThread) {315serverThread = new Thread() {316public void run() {317try {318doServerSide();319} catch (Exception e) {320/*321* Our server thread just died.322*323* Release the client, if not active already...324*/325System.err.println("Server died...");326serverReady = true;327serverException = e;328}329}330};331serverThread.start();332} else {333try {334doServerSide();335} catch (Exception e) {336serverException = e;337} finally {338serverReady = true;339}340}341}342343void startClient(boolean newThread) throws Exception {344if (newThread) {345clientThread = new Thread() {346public void run() {347try {348doClientSide();349} catch (Exception e) {350/*351* Our client thread just died.352*/353System.err.println("Client died...");354clientException = e;355}356}357};358clientThread.start();359} else {360try {361doClientSide();362} catch (Exception e) {363clientException = e;364}365}366}367368369class MyExtendedX509TM extends X509ExtendedTrustManager370implements X509TrustManager {371372X509TrustManager tm;373374MyExtendedX509TM(X509TrustManager tm) {375this.tm = tm;376}377378public void checkClientTrusted(X509Certificate chain[], String authType)379throws CertificateException {380tm.checkClientTrusted(chain, authType);381}382383public void checkServerTrusted(X509Certificate chain[], String authType)384throws CertificateException {385tm.checkServerTrusted(chain, authType);386}387388public X509Certificate[] getAcceptedIssuers() {389List<X509Certificate> certs = new ArrayList<>();390try {391for (X509Certificate c : tm.getAcceptedIssuers()) {392if (serverKS.getCertificateAlias(c).equals(keyAlias))393certs.add(c);394}395} catch (KeyStoreException kse) {396throw new RuntimeException(kse);397}398return certs.toArray(new X509Certificate[certs.size()]);399}400401public void checkClientTrusted(X509Certificate[] chain, String authType,402Socket socket) throws CertificateException {403tm.checkClientTrusted(chain, authType);404}405406public void checkServerTrusted(X509Certificate[] chain, String authType,407Socket socket) throws CertificateException {408tm.checkServerTrusted(chain, authType);409}410411public void checkClientTrusted(X509Certificate[] chain, String authType,412SSLEngine engine) throws CertificateException {413tm.checkClientTrusted(chain, authType);414}415416public void checkServerTrusted(X509Certificate[] chain, String authType,417SSLEngine engine) throws CertificateException {418tm.checkServerTrusted(chain, authType);419}420}421422}423424425426