Path: blob/master/test/jdk/sun/security/ssl/SSLContextImpl/MD2InTrustAnchor.java
41152 views
/*1* Copyright (c) 2011, 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. Oracle designates this7* particular file as subject to the "Classpath" exception as provided8* by Oracle in the LICENSE file that accompanied this code.9*10* This code is distributed in the hope that it will be useful, but WITHOUT11* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or12* FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License13* version 2 for more details (a copy is included in the LICENSE file that14* accompanied this code).15*16* You should have received a copy of the GNU General Public License version17* 2 along with this work; if not, write to the Free Software Foundation,18* Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.19*20* Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA21* or visit www.oracle.com if you need additional information or have any22* questions.23*/2425//26// SunJSSE does not support dynamic system properties, no way to re-use27// system properties in samevm/agentvm mode.28//2930/*31* @test32* @bug 711327533* @summary compatibility issue with MD2 trust anchor and old X509TrustManager34* @run main/othervm MD2InTrustAnchor PKIX TLSv1.135* @run main/othervm MD2InTrustAnchor SunX509 TLSv1.136* @run main/othervm MD2InTrustAnchor PKIX TLSv1.237* @run main/othervm MD2InTrustAnchor SunX509 TLSv1.238*/39import java.io.ByteArrayInputStream;40import java.io.InputStream;41import java.io.OutputStream;42import javax.net.ssl.*;43import java.security.Security;44import java.security.KeyStore;45import java.security.KeyFactory;46import java.security.cert.Certificate;47import java.security.cert.CertificateFactory;48import java.security.interfaces.RSAPrivateKey;49import java.security.spec.PKCS8EncodedKeySpec;50import java.util.Base64;51import java.util.concurrent.CountDownLatch;5253public class MD2InTrustAnchor {5455/*56* Certificates and key used in the test.57*/58// It's a trust anchor signed with MD2 hash function.59private static final String TRUSTED_CERT_STR = "-----BEGIN CERTIFICATE-----\n"60+ "MIICkjCCAfugAwIBAgIBADANBgkqhkiG9w0BAQIFADA7MQswCQYDVQQGEwJVUzEN\n"61+ "MAsGA1UEChMESmF2YTEdMBsGA1UECxMUU3VuSlNTRSBUZXN0IFNlcml2Y2UwHhcN\n"62+ "MTExMTE4MTExNDA0WhcNMzIxMDI4MTExNDA0WjA7MQswCQYDVQQGEwJVUzENMAsG\n"63+ "A1UEChMESmF2YTEdMBsGA1UECxMUU3VuSlNTRSBUZXN0IFNlcml2Y2UwgZ8wDQYJ\n"64+ "KoZIhvcNAQEBBQADgY0AMIGJAoGBAPGyB9tugUGgxtdeqe0qJEwf9x1Gy4BOi1yR\n"65+ "wzDZY4H5LquvIfQ2V3J9X1MQENVsFvkvp65ZcFcy+ObOucXUUPFcd/iw2DVb5QXA\n"66+ "ffyeVqWD56GPi8Qe37wrJO3L6fBhN9oxp/BbdRLgjU81zx8qLEyPODhPMxV4OkcA\n"67+ "SDwZTSxxAgMBAAGjgaUwgaIwHQYDVR0OBBYEFLOAtr/YrYj9H04EDLA0fd14jisF\n"68+ "MGMGA1UdIwRcMFqAFLOAtr/YrYj9H04EDLA0fd14jisFoT+kPTA7MQswCQYDVQQG\n"69+ "EwJVUzENMAsGA1UEChMESmF2YTEdMBsGA1UECxMUU3VuSlNTRSBUZXN0IFNlcml2\n"70+ "Y2WCAQAwDwYDVR0TAQH/BAUwAwEB/zALBgNVHQ8EBAMCAQYwDQYJKoZIhvcNAQEC\n"71+ "BQADgYEAr8ExpXu/FTIRiMzPm0ubqwME4lniilwQUiEOD/4DbksNjEIcUyS2hIk1\n"72+ "qsmjJz3SHBnwhxl9dhJVwk2tZLkPGW86Zn0TPVRsttK4inTgCC9GFGeqQBdrU/uf\n"73+ "lipBzXWljrfbg4N/kK8m2LabtKUMMnGysM8rN0Fx2PYm5xxGvtM=\n"74+ "-----END CERTIFICATE-----";7576// The certificate issued by above trust anchor, signed with MD577private static final String TARGET_CERT_STR = "-----BEGIN CERTIFICATE-----\n"78+ "MIICeDCCAeGgAwIBAgIBAjANBgkqhkiG9w0BAQQFADA7MQswCQYDVQQGEwJVUzEN\n"79+ "MAsGA1UEChMESmF2YTEdMBsGA1UECxMUU3VuSlNTRSBUZXN0IFNlcml2Y2UwHhcN\n"80+ "MTExMTE4MTExNDA2WhcNMzEwODA1MTExNDA2WjBPMQswCQYDVQQGEwJVUzENMAsG\n"81+ "A1UEChMESmF2YTEdMBsGA1UECxMUU3VuSlNTRSBUZXN0IFNlcml2Y2UxEjAQBgNV\n"82+ "BAMTCWxvY2FsaG9zdDCBnzANBgkqhkiG9w0BAQEFAAOBjQAwgYkCgYEAwDnm96mw\n"83+ "fXCH4bgXk1US0VcJsQVxUtGMyncAveMuzBzNzOmKZPeqyYX1Fuh4q+cuza03WTJd\n"84+ "G9nOkNr364e3Rn1aaHjCMcBmFflObnGnhhufNmIGYogJ9dJPmhUVPEVAXrMG+Ces\n"85+ "NKy2E8woGnLMrqu6yiuTClbLBPK8fWzTXrECAwEAAaN4MHYwCwYDVR0PBAQDAgPo\n"86+ "MB0GA1UdDgQWBBSdRrpocLPJXyGfDmMWJrcEf29WGDAfBgNVHSMEGDAWgBSzgLa/\n"87+ "2K2I/R9OBAywNH3deI4rBTAnBgNVHSUEIDAeBggrBgEFBQcDAQYIKwYBBQUHAwIG\n"88+ "CCsGAQUFBwMDMA0GCSqGSIb3DQEBBAUAA4GBAKJ71ZiCUykkJrCLYUxlFlhvUcr9\n"89+ "sTcOc67QdroW5f412NI15SXWDiley/JOasIiuIFPjaJBjOKoHOvTjG/snVu9wEgq\n"90+ "YNR8dPsO+NM8r79C6jO+Jx5fYAC7os2XxS75h3NX0ElJcbwIXGBJ6xRrsFh/BGYH\n"91+ "yvudOlX4BkVR0l1K\n"92+ "-----END CERTIFICATE-----";9394// Private key in the format of PKCS#8.95private static final String TARGET_PRIV_KEY_STR = "MIICdwIBADANBgkqhkiG9w0B\n"96+ "AQEFAASCAmEwggJdAgEAAoGBAMA55vepsH1wh+G4F5NVEtFXCbEFcVLRjMp3AL3j\n"97+ "LswczczpimT3qsmF9RboeKvnLs2tN1kyXRvZzpDa9+uHt0Z9Wmh4wjHAZhX5Tm5x\n"98+ "p4YbnzZiBmKICfXST5oVFTxFQF6zBvgnrDSsthPMKBpyzK6rusorkwpWywTyvH1s\n"99+ "016xAgMBAAECgYEAn9bF3oRkdDoBU0i/mcww5I+KSH9tFt+WQbiojjz9ac49trkv\n"100+ "Ufu7MO1Jui2+QbrvaSkyj+HYGFOJd1wMsPXeB7ck5mOIYV4uZK8jfNMSQ8v0tFEe\n"101+ "IPp5lKdw1XnrQfSe+abo2eL5Lwso437Y4s3w37+HaY3d76hR5qly+Ys+Ww0CQQDj\n"102+ "eOoX89d/xhRqGXKjCx8ImE/dPmsI8O27cwtKrDYJ6t0v/xryVIdvOYcRBvKnqEog\n"103+ "OH7T1kI+LnWKUTJ2ehJ7AkEA2FVloPVqCehXcc7ez3TDpU9w1B0JXklcV5HddYsR\n"104+ "qp9RukN/VK4szKE7F1yoarIUtfE9Lr9082Jwyp3ML11xwwJBAKsZ+Hur3x0tUY29\n"105+ "No2Nf/pnFyvEF57SGwA0uPmiL8Ol9lpz+UDudDElhIM6Rqv12kwCMuQE9i7vo1o3\n"106+ "WU3k5KECQEqhg1L49yD935TqiiFFpe0Ur9btQXsekdXAA4d2d5zGI7q/aGD9SYU6\n"107+ "phkUJSHR16VA2RuUfzMrpb+wmm1IrmMCQFtLoKRTA5kokFb+E3Gplu29tJvCUpfw\n"108+ "gBFRS+wmkvtiaU/tiyDcVgDO+An5DwedxxdVzqiEnjWHoKY3axDQ8OU=";109110private static final char PASSPHRASE[] = "passphrase".toCharArray();111112/*113* Is the server ready to serve?114*/115private static volatile CountDownLatch sync = new CountDownLatch(1);116117/*118* Turn on SSL debugging?119*/120private static final boolean DEBUG = false;121122/*123* Define the server side of the test.124*125* If the server prematurely exits, serverReady will be set to true126* to avoid infinite hangs.127*/128private void doServerSide() throws Exception {129SSLContext context = generateSSLContext(TRUSTED_CERT_STR, TARGET_CERT_STR,130TARGET_PRIV_KEY_STR);131SSLServerSocketFactory sslssf = context.getServerSocketFactory();132try (SSLServerSocket sslServerSocket133= (SSLServerSocket) sslssf.createServerSocket(serverPort)) {134sslServerSocket.setNeedClientAuth(true);135serverPort = sslServerSocket.getLocalPort();136/*137* Signal Client, we're ready for his connect.138*/139System.out.println("Signal server ready");140sync.countDown();141142System.out.println("Waiting for client connection");143try (SSLSocket sslSocket = (SSLSocket) sslServerSocket.accept()) {144InputStream sslIS = sslSocket.getInputStream();145OutputStream sslOS = sslSocket.getOutputStream();146147sslIS.read();148sslOS.write('A');149sslOS.flush();150}151}152}153154/*155* Define the client side of the test.156*157* If the server prematurely exits, serverReady will be set to true158* to avoid infinite hangs.159*/160private void doClientSide() throws Exception {161162/*163* Wait for server to get started.164*/165System.out.println("Waiting for server ready");166sync.await();167168SSLContext context = generateSSLContext(TRUSTED_CERT_STR, TARGET_CERT_STR,169TARGET_PRIV_KEY_STR);170SSLSocketFactory sslsf = context.getSocketFactory();171172System.out.println("Connect to server on port: " + serverPort);173try (SSLSocket sslSocket174= (SSLSocket) sslsf.createSocket("localhost", serverPort)) {175// enable the specified TLS protocol176sslSocket.setEnabledProtocols(new String[]{tlsProtocol});177178InputStream sslIS = sslSocket.getInputStream();179OutputStream sslOS = sslSocket.getOutputStream();180181sslOS.write('B');182sslOS.flush();183sslIS.read();184}185}186187/*188* =============================================================189* The remainder is just support stuff190*/191private static String tmAlgorithm; // trust manager192private static String tlsProtocol; // trust manager193194private static void parseArguments(String[] args) {195tmAlgorithm = args[0];196tlsProtocol = args[1];197}198199private static SSLContext generateSSLContext(String trustedCertStr,200String keyCertStr, String keySpecStr) throws Exception {201202// generate certificate from cert string203CertificateFactory cf = CertificateFactory.getInstance("X.509");204205// create a key store206KeyStore ks = KeyStore.getInstance("JKS");207ks.load(null, null);208209// import the trused cert210Certificate trusedCert = null;211ByteArrayInputStream is = null;212if (trustedCertStr != null) {213is = new ByteArrayInputStream(trustedCertStr.getBytes());214trusedCert = cf.generateCertificate(is);215is.close();216217ks.setCertificateEntry("RSA Export Signer", trusedCert);218}219220if (keyCertStr != null) {221// generate the private key.222PKCS8EncodedKeySpec priKeySpec = new PKCS8EncodedKeySpec(223Base64.getMimeDecoder().decode(keySpecStr));224KeyFactory kf = KeyFactory.getInstance("RSA");225RSAPrivateKey priKey226= (RSAPrivateKey) kf.generatePrivate(priKeySpec);227228// generate certificate chain229is = new ByteArrayInputStream(keyCertStr.getBytes());230Certificate keyCert = cf.generateCertificate(is);231is.close();232233// It's not allowed to send MD2 signed certificate to peer,234// even it may be a trusted certificate. Then we will not235// place the trusted certficate in the chain.236Certificate[] chain = new Certificate[1];237chain[0] = keyCert;238239// import the key entry.240ks.setKeyEntry("Whatever", priKey, PASSPHRASE, chain);241}242243// create SSL context244TrustManagerFactory tmf = TrustManagerFactory.getInstance(tmAlgorithm);245tmf.init(ks);246247SSLContext ctx = SSLContext.getInstance(tlsProtocol);248if (keyCertStr != null && !keyCertStr.isEmpty()) {249KeyManagerFactory kmf = KeyManagerFactory.getInstance("NewSunX509");250kmf.init(ks, PASSPHRASE);251252ctx.init(kmf.getKeyManagers(), tmf.getTrustManagers(), null);253ks = null;254} else {255ctx.init(null, tmf.getTrustManagers(), null);256}257258return ctx;259}260261// use any free port by default262private volatile int serverPort = 0;263264private volatile Exception serverException = null;265266public static void main(String[] args) throws Exception {267// MD5 is used in this test case, don't disable MD5 algorithm.268Security.setProperty("jdk.certpath.disabledAlgorithms",269"MD2, RSA keySize < 1024");270Security.setProperty("jdk.tls.disabledAlgorithms",271"SSLv3, RC4, DH keySize < 768");272273if (DEBUG) {274System.setProperty("javax.net.debug", "all");275}276277/*278* Get the customized arguments.279*/280parseArguments(args);281/*282* Start the tests.283*/284new MD2InTrustAnchor().runTest();285}286287private Thread serverThread = null;288289/*290* Used to drive remainder of the test.291*292* Fork off the other side, then do your work.293*/294public void runTest() throws Exception {295startServerThread();296doClientSide();297298/*299* Wait for other side to close down.300*/301serverThread.join();302303if (serverException != null) {304throw serverException;305}306}307308private void startServerThread() {309serverThread = new Thread() {310@Override311public void run() {312try {313doServerSide();314} catch (Exception e) {315/*316* Our server thread just died.317*318* Release the client, if not active already...319*/320System.err.println("Server died...");321e.printStackTrace(System.out);322serverException = e;323sync.countDown();324}325}326};327328serverThread.start();329}330}331332333