Path: blob/master/test/jdk/sun/security/ssl/X509TrustManagerImpl/SelfIssuedCert.java
41152 views
/*1* Copyright (c) 2009, 2019, 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// SunJSSE does not support dynamic system properties, no way to re-use25// system properties in samevm/agentvm mode.26//2728/*29* @test30* @bug 682246031* @summary support self-issued certificate32* @run main/othervm SelfIssuedCert PKIX33* @run main/othervm SelfIssuedCert SunX50934* @author Xuelei Fan35*/3637import java.io.*;38import javax.net.ssl.*;39import java.security.KeyStore;40import java.security.KeyFactory;41import java.security.cert.Certificate;42import java.security.cert.CertificateFactory;43import java.security.spec.*;44import java.security.interfaces.*;4546import java.util.Base64;4748public class SelfIssuedCert {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 = true;6263/*64* Where do we find the keystores?65*/66// Certificate information:67// Issuer: C=US, O=Example, CN=localhost68// Validity69// Not Before: Dec 19 06:11:58 2019 GMT70// Not After : Dec 16 06:11:58 2029 GMT71// Subject: C=US, O=Example, CN=localhost72// X509v3 Subject Key Identifier:73// 80:67:BA:EE:10:6A:E3:8E:3E:8E:F7:2D:90:B6:FD:F9:54:87:47:B174// X509v3 Authority Key Identifier:75// keyid:80:67:BA:EE:10:6A:E3:8E:3E:8E:F7:2D:90:B6:FD:F9:54:87:47:B176static String trusedCertStr =77"-----BEGIN CERTIFICATE-----\n" +78"MIIDRzCCAi+gAwIBAgIUFjy13iZYWMGQcGF4svfix/9q4dcwDQYJKoZIhvcNAQEL\n" +79"BQAwMzELMAkGA1UEBhMCVVMxEDAOBgNVBAoMB0V4YW1wbGUxEjAQBgNVBAMMCWxv\n" +80"Y2FsaG9zdDAeFw0xOTEyMTkwNjExNThaFw0yOTEyMTYwNjExNThaMDMxCzAJBgNV\n" +81"BAYTAlVTMRAwDgYDVQQKDAdFeGFtcGxlMRIwEAYDVQQDDAlsb2NhbGhvc3QwggEi\n" +82"MA0GCSqGSIb3DQEBAQUAA4IBDwAwggEKAoIBAQCy57BG8Dt+a4ZwWGM07f0z/mzK\n" +83"T/myXM4W//3pkZxO0+4oyYM7G8ks9O64NPpA0CpTPCpfY6dI1Y/kwBUdSoqx2D8t\n" +84"OEfHOat2/AQvvWmEChFH4ZmmQFkLXBy0ueDq0TJbEd94+WhL3q9bA4uqvBsuuaTt\n" +85"bX/GyOC52bpjg0TWY4BRdRVhveISZvqOCoqqJ1aPOnfxqySaZIC34q9gdUCUNxZD\n" +86"qjhuQF3Q0xYsNGZSUmnKj3/0GS600BwQPqSHy287Vda88NvqJGFS4DKrw3HV3Wsk\n" +87"IHGN+tzB5THBy70XrE+XIdXJ/I86q+FvNcTnJygn2nVNG4+vUhW8S3BzTiKPAgMB\n" +88"AAGjUzBRMB0GA1UdDgQWBBSAZ7ruEGrjjj6O9y2Qtv35VIdHsTAfBgNVHSMEGDAW\n" +89"gBSAZ7ruEGrjjj6O9y2Qtv35VIdHsTAPBgNVHRMBAf8EBTADAQH/MA0GCSqGSIb3\n" +90"DQEBCwUAA4IBAQBX7icKmR/iUPJhfnvNHiqsyTIcowY3JSAJAyJFrViKx2tdo+qq\n" +91"yA+EUsZlZsCwhiiG4/SjFxgaAp0Z3BBmsO/njWUEx3/fSufTHcs0+fPNkFLru5Lr\n" +92"das4wW9Cv/wO4rz2L6qK/x7+r/wkPccaqxTpdZvXqDid2va5Lv3F7jOW5ns13piZ\n" +93"z571RCpmhGSytYKFrAOGoI4ZBWXrkCiYQZ8KvhdBQP/MNJM+e6ajtF27rK08XTao\n" +94"mW3FXfK6SjKQDGVwtNJ7M1qGutIpe0pNBGwvDpQuY2mk0Le46OXdaQ7AAzE+OnRJ\n" +95"1uRDV+p95MzhtolPgB3I8Rzyd23nfrx6uxMA\n" +96"-----END CERTIFICATE-----";9798// Certificate information:99// Issuer: C=US, O=Example, CN=localhost100// Validity101// Not Before: Dec 19 06:12:04 2019 GMT102// Not After : Dec 16 06:12:04 2029 GMT103// Subject: C=US, O=Example, CN=localhost104// X509v3 Subject Key Identifier:105// 73:79:B7:73:F5:41:BB:3A:90:07:87:F2:CA:A5:B3:C3:45:E0:18:E0106// X509v3 Authority Key Identifier:107// keyid:80:67:BA:EE:10:6A:E3:8E:3E:8E:F7:2D:90:B6:FD:F9:54:87:47:B1108static String targetCertStr =109"-----BEGIN CERTIFICATE-----\n" +110"MIIDNjCCAh6gAwIBAgIURM+bID1TFw41Z/Vz9tPp7HzpH7QwDQYJKoZIhvcNAQEL\n" +111"BQAwMzELMAkGA1UEBhMCVVMxEDAOBgNVBAoMB0V4YW1wbGUxEjAQBgNVBAMMCWxv\n" +112"Y2FsaG9zdDAeFw0xOTEyMTkwNjEyMDRaFw0yOTEyMTYwNjEyMDRaMDMxCzAJBgNV\n" +113"BAYTAlVTMRAwDgYDVQQKDAdFeGFtcGxlMRIwEAYDVQQDDAlsb2NhbGhvc3QwggEi\n" +114"MA0GCSqGSIb3DQEBAQUAA4IBDwAwggEKAoIBAQCtxQXQdTlZNoASIE0TM+tgtUY3\n" +115"jnu0EymO+RGljOIFYhz2MxN0OQ5ABofxdIhbSqtoCO9HbsVWIPKOvbACoAJ4HjTV\n" +116"antLPlvCqbUoR96q6JWbnbQ6uZOsgiQTveQMhLJ+k9BehzcwKvwCFGNY3qW0xwUv\n" +117"mXKWRveRAbTOjZ3i1YzcmkLOwYaeyt2Al3jPCbZySUlB94NRRAQZ4RzqfuetAvEd\n" +118"LFW1fXNwL5bHE7JbJkWInciLOqHf5GuyXDjKE8Oz2/Ywv/5C2K2LtWa1g5jIEQtB\n" +119"cjRa9Cjwcrs8peisC5OmL5cbJweNKr6H0mrVR8KFdFHUmM5X4uSiOMVFr/rTAgMB\n" +120"AAGjQjBAMB0GA1UdDgQWBBRzebdz9UG7OpAHh/LKpbPDReAY4DAfBgNVHSMEGDAW\n" +121"gBSAZ7ruEGrjjj6O9y2Qtv35VIdHsTANBgkqhkiG9w0BAQsFAAOCAQEAZ/Ijlics\n" +122"YGCw9k4he3ZkNfqCPFTJKgkbTuM1Cy+aCXzhhdGKCZ2R0Xyi3ma3snwPtqHy5Aru\n" +123"WwoGssxL6S8+Pb/BPZ9OelU7lEmS69AeBKOHHIEs+wEi2oco8J+WU1O4zekP8Clv\n" +124"hHuwPhoL6g0aAUXAISaqYpHYC15oXGOJcC539kgv4VrL9UZJekxtDERUXKyzW+UC\n" +125"ZBPalts1zM5wD43+9PuoeLiPdvMg1kH4obJYnj23zej41iwqPOWhgm0NuGoJVjSg\n" +126"4YqtS1ePD/I2oRV0bu4P7Q72cMYdcFHfPDoe3vCcEMxUTgGBaoPHw9GwEeRoWn/L\n" +127"whBwzXBsD0aZqQ==\n" +128"-----END CERTIFICATE-----";129130// Private key in the format of PKCS#8131static String targetPrivateKey =132"MIIEvAIBADANBgkqhkiG9w0BAQEFAASCBKYwggSiAgEAAoIBAQCtxQXQdTlZNoAS\n" +133"IE0TM+tgtUY3jnu0EymO+RGljOIFYhz2MxN0OQ5ABofxdIhbSqtoCO9HbsVWIPKO\n" +134"vbACoAJ4HjTVantLPlvCqbUoR96q6JWbnbQ6uZOsgiQTveQMhLJ+k9BehzcwKvwC\n" +135"FGNY3qW0xwUvmXKWRveRAbTOjZ3i1YzcmkLOwYaeyt2Al3jPCbZySUlB94NRRAQZ\n" +136"4RzqfuetAvEdLFW1fXNwL5bHE7JbJkWInciLOqHf5GuyXDjKE8Oz2/Ywv/5C2K2L\n" +137"tWa1g5jIEQtBcjRa9Cjwcrs8peisC5OmL5cbJweNKr6H0mrVR8KFdFHUmM5X4uSi\n" +138"OMVFr/rTAgMBAAECggEAIFDvz+C9FZZJIxXWv6d8MrQDpvlckBSwOeKgIYWd0xp4\n" +139"AGFnUMn7mHSee40Mfs3YKrTeqw4yrN3bvigQv6w6SVR0xuvSmh+yuPUOt7sF8grn\n" +140"J9WgWvuANyjMxM8fxiQ3fcrHiYzj+pVD4K8h+rkNYB1THZMP+FqiV9lVYsR7hF+b\n" +141"1D967LB4oLmAaMExaSo23NZLGVTxZSxxGw6Qidz7CyKvIdVXnNIEzMnuXX60xiJm\n" +142"PnLyZUKDmlw5kI4KaDG+6OIOpDu2FGCFVLZmycs4Ri6h6xJp3jhKAVjCcZJUty80\n" +143"+rBfAx4BHfDrcgyEiTN7NA8gnnCzUc6uX6I/tm62gQKBgQDniWuFjSzhaAhj04+N\n" +144"vG8sQjfVmTbON6SfFfujR/Z57qamJ8zcS/REHfc5swdn9uUTJ2xoRRNCwKZyuMXo\n" +145"4B2/O9+sKfEPYGyjAyGo6E4rGLRNcw6Tb8hx/EFvfTOunwapynOJDDs2Z6FzWNIx\n" +146"x4+FHs9hStwL/OTdXF/OY2vGsQKBgQDAIR93LrCC6OpGi89/UDIwpT9pFLa8cvpr\n" +147"1MUNlHhcxQusPUgWT4pTucF/SQpPf77g3YNb5pt3DG0GELM8YAB0Uv9oZIWfJoFY\n" +148"ebYy6tMVxhHhT0OuryMj48BMHnQG78hq8+c0NnjK7jXV6t0iKjN8ANnFqAovm+U9\n" +149"VMobar5CwwKBgFCKN9GsCxmZg5meBQiLrKxbmGp/slXHe0cvcWoZ5T4C6wtPOu7C\n" +150"qQRs3AvBH+llM8gW5ZnbtVh6BSxQ498e3pof7K1JpaXwp7mIpFPKAy7wl/9872wP\n" +151"7UzhL63lgm3SuZGkb84TaCGDqOCj2/Ie9eibkA3K6YJuBPqPYHA9m0bxAoGARdcE\n" +152"iB9pvHyMRM6nw8DULciz7y+/aWtmSnJSmyggRKDAKIEyRiHtx5eblfhoDhQCv9zl\n" +153"1i9SzgivTOgfL1A6eg59l2YLCJpHpHDB4WppBt40O7HDialSXcZ5bXIYfTkGopI8\n" +154"tkciy6mh2jwA3F14z5fDkc0OvtWtlAjRWvwHY18CgYAPONVJtVFiMogBU5Iyv1LB\n" +155"oygn6AFvTI8Pjy2g5GsJBbRnKFjAJrP7HpgUxLdW+Mlnv3Xgtr/L6ep+VKoXTEwv\n" +156"Y83gliDwG2YRjaUbkMfQqcm20/Pi4XPwhy5pwTVsXVBfzKzqJjKAFk97BD9xCUIH\n" +157"FOGe+jaEsWvaEQrH5y17FQ==";158159static char passphrase[] = "passphrase".toCharArray();160161/*162* Is the server ready to serve?163*/164volatile static boolean serverReady = false;165166/*167* Turn on SSL debugging?168*/169static boolean debug = false;170171/*172* Define the server side of the test.173*174* If the server prematurely exits, serverReady will be set to true175* to avoid infinite hangs.176*/177void doServerSide() throws Exception {178SSLContext context = getSSLContext(null, targetCertStr,179targetPrivateKey);180SSLServerSocketFactory sslssf = context.getServerSocketFactory();181182SSLServerSocket sslServerSocket =183(SSLServerSocket)sslssf.createServerSocket(serverPort);184serverPort = sslServerSocket.getLocalPort();185186/*187* Signal Client, we're ready for his connect.188*/189serverReady = true;190191SSLSocket sslSocket = (SSLSocket) sslServerSocket.accept();192sslSocket.setNeedClientAuth(false);193194InputStream sslIS = sslSocket.getInputStream();195OutputStream sslOS = sslSocket.getOutputStream();196197sslIS.read();198sslOS.write(85);199sslOS.flush();200201sslSocket.close();202203}204205/*206* Define the client side of the test.207*208* If the server prematurely exits, serverReady will be set to true209* to avoid infinite hangs.210*/211void doClientSide() throws Exception {212/*213* Wait for server to get started.214*/215while (!serverReady) {216Thread.sleep(50);217}218219SSLContext context = getSSLContext(trusedCertStr, null, null);220SSLSocketFactory sslsf = context.getSocketFactory();221222SSLSocket sslSocket =223(SSLSocket)sslsf.createSocket("localhost", serverPort);224225InputStream sslIS = sslSocket.getInputStream();226OutputStream sslOS = sslSocket.getOutputStream();227228sslOS.write(280);229sslOS.flush();230sslIS.read();231232sslSocket.close();233}234235// get the ssl context236private static SSLContext getSSLContext(String trusedCertStr,237String keyCertStr, String keySpecStr) throws Exception {238239// generate certificate from cert string240CertificateFactory cf = CertificateFactory.getInstance("X.509");241242// create a key store243KeyStore ks = KeyStore.getInstance("JKS");244ks.load(null, null);245246// import the trused cert247Certificate trusedCert = null;248ByteArrayInputStream is = null;249if (trusedCertStr != null) {250is = new ByteArrayInputStream(trusedCertStr.getBytes());251trusedCert = cf.generateCertificate(is);252is.close();253254ks.setCertificateEntry("RSA Export Signer", trusedCert);255}256257if (keyCertStr != null) {258// generate the private key.259PKCS8EncodedKeySpec priKeySpec = new PKCS8EncodedKeySpec(260Base64.getMimeDecoder().decode(keySpecStr));261KeyFactory kf = KeyFactory.getInstance("RSA");262RSAPrivateKey priKey =263(RSAPrivateKey)kf.generatePrivate(priKeySpec);264265// generate certificate chain266is = new ByteArrayInputStream(keyCertStr.getBytes());267Certificate keyCert = cf.generateCertificate(is);268is.close();269270Certificate[] chain = null;271if (trusedCert != null) {272chain = new Certificate[2];273chain[0] = keyCert;274chain[1] = trusedCert;275} else {276chain = new Certificate[1];277chain[0] = keyCert;278}279280// import the key entry.281ks.setKeyEntry("Whatever", priKey, passphrase, chain);282}283284// create SSL context285TrustManagerFactory tmf = TrustManagerFactory.getInstance(tmAlgorithm);286tmf.init(ks);287288SSLContext ctx = SSLContext.getInstance("TLS");289if (keyCertStr != null && !keyCertStr.isEmpty()) {290KeyManagerFactory kmf = KeyManagerFactory.getInstance("NewSunX509");291kmf.init(ks, passphrase);292293ctx.init(kmf.getKeyManagers(), tmf.getTrustManagers(), null);294ks = null;295} else {296ctx.init(null, tmf.getTrustManagers(), null);297}298299return ctx;300}301302private static String tmAlgorithm; // trust manager303304private static void parseArguments(String[] args) {305tmAlgorithm = args[0];306}307308/*309* =============================================================310* The remainder is just support stuff311*/312313// use any free port by default314volatile int serverPort = 0;315316volatile Exception serverException = null;317volatile Exception clientException = null;318319public static void main(String args[]) throws Exception {320if (debug)321System.setProperty("javax.net.debug", "all");322323/*324* Get the customized arguments.325*/326parseArguments(args);327328/*329* Start the tests.330*/331new SelfIssuedCert();332}333334Thread clientThread = null;335Thread serverThread = null;336/*337* Primary constructor, used to drive remainder of the test.338*339* Fork off the other side, then do your work.340*/341SelfIssuedCert() throws Exception {342if (separateServerThread) {343startServer(true);344startClient(false);345} else {346startClient(true);347startServer(false);348}349350/*351* Wait for other side to close down.352*/353if (separateServerThread) {354serverThread.join();355} else {356clientThread.join();357}358359/*360* When we get here, the test is pretty much over.361*362* If the main thread excepted, that propagates back363* immediately. If the other thread threw an exception, we364* should report back.365*/366if (serverException != null)367throw serverException;368if (clientException != null)369throw clientException;370}371372void startServer(boolean newThread) throws Exception {373if (newThread) {374serverThread = new Thread() {375public void run() {376try {377doServerSide();378} catch (Exception e) {379/*380* Our server thread just died.381*382* Release the client, if not active already...383*/384System.err.println("Server died...");385serverReady = true;386serverException = e;387}388}389};390serverThread.start();391} else {392doServerSide();393}394}395396void startClient(boolean newThread) throws Exception {397if (newThread) {398clientThread = new Thread() {399public void run() {400try {401doClientSide();402} catch (Exception e) {403/*404* Our client thread just died.405*/406System.err.println("Client died...");407clientException = e;408}409}410};411clientThread.start();412} else {413doClientSide();414}415}416417}418419420