Path: blob/master/test/jdk/sun/security/mscapi/ShortRSAKeyWithinTLS.java
41149 views
/*1* Copyright (c) 2012, 2018, 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/*24* @test25* @bug 7106773 818057026* @summary 512 bits RSA key cannot work with SHA384 and SHA51227* @requires os.family == "windows"28* @modules java.base/sun.security.util29* java.base/sun.security.tools.keytool30* java.base/sun.security.x50931* @run main ShortRSAKeyWithinTLS 102432* @run main ShortRSAKeyWithinTLS 76833* @run main ShortRSAKeyWithinTLS 51234*/35import java.io.*;36import java.net.*;37import java.security.cert.Certificate;38import java.util.*;39import java.security.*;40import java.security.cert.*;41import javax.net.*;42import javax.net.ssl.*;4344import sun.security.tools.keytool.CertAndKeyGen;45import sun.security.util.KeyUtil;46import sun.security.x509.X500Name;4748public class ShortRSAKeyWithinTLS {4950/*51* =============================================================52* Set the various variables needed for the tests, then53* specify what tests to run on each side.54*/5556/*57* Should we run the client or server in a separate thread?58* Both sides can throw exceptions, but do you have a preference59* as to which side should be the main thread.60*/61static boolean separateServerThread = false;6263/*64* Is the server ready to serve?65*/66volatile static boolean serverReady = false;6768/*69* Turn on SSL debugging?70*/71static boolean debug = false;7273/*74* If the client or server is doing some kind of object creation75* that the other side depends on, and that thread prematurely76* exits, you may experience a hang. The test harness will77* terminate all hung threads after its timeout has expired,78* currently 3 minutes by default, but you might try to be79* smart about it....80*/8182/*83* Define the server side of the test.84*85* If the server prematurely exits, serverReady will be set to true86* to avoid infinite hangs.87*/88void doServerSide() throws Exception {8990// load the key store91serverKS = KeyStore.getInstance("Windows-MY", "SunMSCAPI");92serverKS.load(null, null);93System.out.println("Loaded keystore: Windows-MY");9495// check key size96checkKeySize(serverKS);9798// initialize the SSLContext99KeyManagerFactory kmf = KeyManagerFactory.getInstance("SunX509");100kmf.init(serverKS, null);101102TrustManagerFactory tmf = TrustManagerFactory.getInstance("SunX509");103tmf.init(serverKS);104TrustManager[] tms = tmf.getTrustManagers();105if (tms == null || tms.length == 0) {106throw new Exception("unexpected trust manager implementation");107} else {108if (!(tms[0] instanceof X509TrustManager)) {109throw new Exception("unexpected trust manager" +110" implementation: " +111tms[0].getClass().getCanonicalName());112}113}114serverTM = new MyExtendedX509TM((X509TrustManager)tms[0]);115tms = new TrustManager[] {serverTM};116117SSLContext ctx = SSLContext.getInstance("TLS");118ctx.init(kmf.getKeyManagers(), tms, null);119120ServerSocketFactory ssf = ctx.getServerSocketFactory();121SSLServerSocket sslServerSocket = (SSLServerSocket)122ssf.createServerSocket(serverPort);123sslServerSocket.setNeedClientAuth(true);124serverPort = sslServerSocket.getLocalPort();125System.out.println("serverPort = " + serverPort);126127/*128* Signal Client, we're ready for his connect.129*/130serverReady = true;131132SSLSocket sslSocket = (SSLSocket) sslServerSocket.accept();133InputStream sslIS = sslSocket.getInputStream();134OutputStream sslOS = sslSocket.getOutputStream();135136sslIS.read();137sslOS.write(85);138sslOS.flush();139140sslSocket.close();141}142143/*144* Define the client side of the test.145*146* If the server prematurely exits, serverReady will be set to true147* to avoid infinite hangs.148*/149void doClientSide() throws Exception {150151/*152* Wait for server to get started.153*/154while (!serverReady) {155Thread.sleep(50);156}157158// load the key store159KeyStore ks = KeyStore.getInstance("Windows-MY", "SunMSCAPI");160ks.load(null, null);161System.out.println("Loaded keystore: Windows-MY");162163// initialize the SSLContext164KeyManagerFactory kmf = KeyManagerFactory.getInstance("SunX509");165kmf.init(ks, null);166167TrustManagerFactory tmf = TrustManagerFactory.getInstance("SunX509");168tmf.init(ks);169170SSLContext ctx = SSLContext.getInstance("TLS");171ctx.init(kmf.getKeyManagers(), tmf.getTrustManagers(), null);172173SSLSocketFactory sslsf = ctx.getSocketFactory();174SSLSocket sslSocket = (SSLSocket)175sslsf.createSocket("localhost", serverPort);176177if (clientProtocol != null) {178sslSocket.setEnabledProtocols(new String[] {clientProtocol});179}180181if (clientCiperSuite != null) {182sslSocket.setEnabledCipherSuites(new String[] {clientCiperSuite});183}184185InputStream sslIS = sslSocket.getInputStream();186OutputStream sslOS = sslSocket.getOutputStream();187188sslOS.write(280);189sslOS.flush();190sslIS.read();191192sslSocket.close();193}194195private void checkKeySize(KeyStore ks) throws Exception {196PrivateKey privateKey = null;197PublicKey publicKey = null;198199if (ks.containsAlias(keyAlias)) {200System.out.println("Loaded entry: " + keyAlias);201privateKey = (PrivateKey)ks.getKey(keyAlias, null);202publicKey = (PublicKey)ks.getCertificate(keyAlias).getPublicKey();203204int privateKeySize = KeyUtil.getKeySize(privateKey);205if (privateKeySize != keySize) {206throw new Exception("Expected key size is " + keySize +207", but the private key size is " + privateKeySize);208}209210int publicKeySize = KeyUtil.getKeySize(publicKey);211if (publicKeySize != keySize) {212throw new Exception("Expected key size is " + keySize +213", but the public key size is " + publicKeySize);214}215}216}217218/*219* =============================================================220* The remainder is just support stuff221*/222223// use any free port by default224volatile int serverPort = 0;225226volatile Exception serverException = null;227volatile Exception clientException = null;228229private static String keyAlias;230private static int keySize;231private static String clientProtocol = null;232private static String clientCiperSuite = null;233234public static void main(String[] args) throws Exception {235if (debug) {236System.setProperty("javax.net.debug", "all");237}238239keyAlias = "7106773." + args[0];240keySize = Integer.parseInt(args[0]);241242KeyStore ks = KeyStore.getInstance("Windows-MY");243ks.load(null, null);244if (ks.containsAlias(keyAlias)) {245ks.deleteEntry(keyAlias);246}247248CertAndKeyGen gen = new CertAndKeyGen("RSA", "SHA256withRSA");249gen.generate(keySize);250251ks.setKeyEntry(keyAlias, gen.getPrivateKey(), null,252new Certificate[] {253gen.getSelfCertificate(new X500Name("cn=localhost,c=US"), 100)254});255256clientProtocol = "TLSv1.2";257clientCiperSuite = "TLS_DHE_RSA_WITH_AES_128_CBC_SHA";258259try {260new ShortRSAKeyWithinTLS();261} finally {262ks.deleteEntry(keyAlias);263ks.store(null, null);264}265}266267Thread clientThread = null;268Thread serverThread = null;269KeyStore serverKS;270MyExtendedX509TM serverTM;271272/*273* Primary constructor, used to drive remainder of the test.274*275* Fork off the other side, then do your work.276*/277ShortRSAKeyWithinTLS() throws Exception {278try {279if (separateServerThread) {280startServer(true);281startClient(false);282} else {283startClient(true);284startServer(false);285}286} catch (Exception e) {287// swallow for now. Show later288}289290/*291* Wait for other side to close down.292*/293if (separateServerThread) {294serverThread.join();295} else {296clientThread.join();297}298299/*300* When we get here, the test is pretty much over.301* Which side threw the error?302*/303Exception local;304Exception remote;305String whichRemote;306307if (separateServerThread) {308remote = serverException;309local = clientException;310whichRemote = "server";311} else {312remote = clientException;313local = serverException;314whichRemote = "client";315}316317/*318* If both failed, return the curthread's exception, but also319* print the remote side Exception320*/321if ((local != null) && (remote != null)) {322System.out.println(whichRemote + " also threw:");323remote.printStackTrace();324System.out.println();325throw local;326}327328if (remote != null) {329throw remote;330}331332if (local != null) {333throw local;334}335}336337void startServer(boolean newThread) throws Exception {338if (newThread) {339serverThread = new Thread() {340public void run() {341try {342doServerSide();343} catch (Exception e) {344/*345* Our server thread just died.346*347* Release the client, if not active already...348*/349System.err.println("Server died...");350serverReady = true;351serverException = e;352}353}354};355serverThread.start();356} else {357try {358doServerSide();359} catch (Exception e) {360serverException = e;361} finally {362serverReady = true;363}364}365}366367void startClient(boolean newThread) throws Exception {368if (newThread) {369clientThread = new Thread() {370public void run() {371try {372doClientSide();373} catch (Exception e) {374/*375* Our client thread just died.376*/377System.err.println("Client died...");378clientException = e;379}380}381};382clientThread.start();383} else {384try {385doClientSide();386} catch (Exception e) {387clientException = e;388}389}390}391392393class MyExtendedX509TM extends X509ExtendedTrustManager394implements X509TrustManager {395396X509TrustManager tm;397398MyExtendedX509TM(X509TrustManager tm) {399this.tm = tm;400}401402public void checkClientTrusted(X509Certificate chain[], String authType)403throws CertificateException {404tm.checkClientTrusted(chain, authType);405}406407public void checkServerTrusted(X509Certificate chain[], String authType)408throws CertificateException {409tm.checkServerTrusted(chain, authType);410}411412public X509Certificate[] getAcceptedIssuers() {413List<X509Certificate> certs = new ArrayList<>();414try {415for (X509Certificate c : tm.getAcceptedIssuers()) {416if (serverKS.getCertificateAlias(c).equals(keyAlias))417certs.add(c);418}419} catch (KeyStoreException kse) {420throw new RuntimeException(kse);421}422return certs.toArray(new X509Certificate[certs.size()]);423}424425public void checkClientTrusted(X509Certificate[] chain, String authType,426Socket socket) throws CertificateException {427tm.checkClientTrusted(chain, authType);428}429430public void checkServerTrusted(X509Certificate[] chain, String authType,431Socket socket) throws CertificateException {432tm.checkServerTrusted(chain, authType);433}434435public void checkClientTrusted(X509Certificate[] chain, String authType,436SSLEngine engine) throws CertificateException {437tm.checkClientTrusted(chain, authType);438}439440public void checkServerTrusted(X509Certificate[] chain, String authType,441SSLEngine engine) throws CertificateException {442tm.checkServerTrusted(chain, authType);443}444}445446}447448449450