1 /* 2 * Copyright (c) 2020, Oracle and/or its affiliates. All rights reserved. 3 * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. 4 * 5 * This code is free software; you can redistribute it and/or modify it 6 * under the terms of the GNU General Public License version 2 only, as 7 * published by the Free Software Foundation. 8 * 9 * This code is distributed in the hope that it will be useful, but WITHOUT 10 * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or 11 * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License 12 * version 2 for more details (a copy is included in the LICENSE file that 13 * accompanied this code). 14 * 15 * You should have received a copy of the GNU General Public License version 16 * 2 along with this work; if not, write to the Free Software Foundation, 17 * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. 18 * 19 * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA 20 * or visit www.oracle.com if you need additional information or have any 21 * questions. 22 */ 23 24 import java.io.IOException; 25 import java.nio.file.Path; 26 import java.nio.file.Paths; 27 import java.security.Security; 28 import java.util.Arrays; 29 import java.util.HashMap; 30 import java.util.List; 31 import java.util.Map; 32 33 /* 34 * A JDK client process. 35 */ 36 public class JdkProcClient extends AbstractClient { 37 38 private final Jdk jdk; 39 private final Map<String, String> props = new HashMap<>(); 40 41 private Process process; 42 JdkProcClient(Builder builder)43 public JdkProcClient(Builder builder) { 44 this.jdk = builder.getJdk(); 45 46 if (builder.getSecPropsFile() != null) { 47 props.put(JdkProcUtils.PROP_SEC_PROPS_FILE, 48 builder.getSecPropsFile().toString()); 49 } 50 51 if (builder.getCertTuple() != null) { 52 props.put(JdkProcUtils.PROP_TRUSTED_CERTS, 53 JdkProcUtils.certsToStr(builder.getCertTuple().trustedCerts)); 54 props.put(JdkProcUtils.PROP_EE_CERTS, 55 JdkProcUtils.certsToStr(builder.getCertTuple().endEntityCerts)); 56 } 57 58 if (builder.getProtocols() != null) { 59 props.put(JdkProcUtils.PROP_PROTOCOLS, 60 Utilities.join(Utilities.enumsToStrs(builder.getProtocols()))); 61 } 62 63 if (builder.getCipherSuites() != null) { 64 props.put(JdkProcUtils.PROP_CIPHER_SUITES, 65 Utilities.join(Utilities.enumsToStrs(builder.getCipherSuites()))); 66 } 67 68 if (builder.getServerNames() != null) { 69 props.put(JdkProcUtils.PROP_SERVER_NAMES, 70 Utilities.join(builder.getServerNames())); 71 } 72 73 if (builder.getAppProtocols() != null) { 74 props.put(JdkProcUtils.PROP_APP_PROTOCOLS, 75 Utilities.join(builder.getAppProtocols())); 76 } 77 78 if (builder.getNamedGroups() != null) { 79 props.put(JdkProcUtils.PROP_NAMED_GROUPS, 80 Utilities.join(Utilities.namedGroupsToStrs( 81 builder.getNamedGroups()))); 82 } 83 84 props.put("test.src", Utilities.TEST_SRC); 85 if (Utilities.DEBUG) { 86 props.put("javax.net.debug", "all"); 87 } 88 } 89 90 public static class Builder extends AbstractClient.Builder { 91 92 private Jdk jdk; 93 94 private Path secPropsFile; 95 getJdk()96 public Jdk getJdk() { 97 return jdk; 98 } 99 setJdk(Jdk jdk)100 public Builder setJdk(Jdk jdk) { 101 this.jdk = jdk; 102 return this; 103 } 104 getSecPropsFile()105 public Path getSecPropsFile() { 106 return secPropsFile; 107 } 108 setSecPropsFile(Path secPropsFile)109 public Builder setSecPropsFile(Path secPropsFile) { 110 this.secPropsFile = secPropsFile; 111 return this; 112 } 113 114 @Override build()115 public JdkProcClient build() { 116 return new JdkProcClient(this); 117 } 118 } 119 120 @Override getProduct()121 public Jdk getProduct() { 122 return jdk; 123 } 124 125 @Override connect(String host, int port)126 public void connect(String host, int port) throws IOException { 127 props.put(JdkProcUtils.PROP_HOST, host); 128 props.put(JdkProcUtils.PROP_PORT, port + ""); 129 130 process = JdkProcUtils.java(getProduct().getPath(), getClass(), props, 131 getLogPath()); 132 try { 133 process.waitFor(); 134 } catch (InterruptedException e) { 135 throw new RuntimeException("Client was interrupted!", e); 136 } 137 138 if (process.exitValue() != 0) { 139 throw new SSLTestException("Client exited abnormally!"); 140 } 141 } 142 143 @Override getLogPath()144 protected Path getLogPath() { 145 return Paths.get("client.log"); 146 } 147 148 @Override close()149 public void close() throws IOException { 150 printLog(); 151 deleteLog(); 152 } 153 main(String[] args)154 public static void main(String[] args) throws Exception { 155 String trustedCertsStr = System.getProperty(JdkProcUtils.PROP_TRUSTED_CERTS); 156 String eeCertsStr = System.getProperty(JdkProcUtils.PROP_EE_CERTS); 157 158 String protocolsStr = System.getProperty(JdkProcUtils.PROP_PROTOCOLS); 159 String cipherSuitesStr = System.getProperty(JdkProcUtils.PROP_CIPHER_SUITES); 160 161 String serverNamesStr = System.getProperty(JdkProcUtils.PROP_SERVER_NAMES); 162 String appProtocolsStr = System.getProperty(JdkProcUtils.PROP_APP_PROTOCOLS); 163 164 // Re-enable TLSv1 and TLSv1.1 since client depends on them 165 removeFromDisabledTlsAlgs("TLSv1", "TLSv1.1"); 166 167 JdkClient.Builder builder = new JdkClient.Builder(); 168 builder.setCertTuple(JdkProcUtils.createCertTuple( 169 trustedCertsStr, eeCertsStr)); 170 if (!Utilities.isEmpty(protocolsStr)) { 171 builder.setProtocols(Utilities.strToEnums( 172 Protocol.class, protocolsStr)); 173 } 174 if (!Utilities.isEmpty(cipherSuitesStr)) { 175 builder.setCipherSuites(Utilities.strToEnums( 176 CipherSuite.class, cipherSuitesStr)); 177 } 178 if (!Utilities.isEmpty(serverNamesStr)) { 179 builder.setServerNames(Utilities.split(serverNamesStr)); 180 } 181 if (!Utilities.isEmpty(appProtocolsStr)) { 182 builder.setAppProtocols(Utilities.split(appProtocolsStr)); 183 } 184 185 String host = System.getProperty(JdkProcUtils.PROP_HOST); 186 int port = Integer.getInteger(JdkProcUtils.PROP_PORT); 187 188 try(JdkClient client = builder.build()) { 189 client.connect(host, port); 190 } 191 } 192 193 /** 194 * Removes the specified protocols from the jdk.tls.disabledAlgorithms 195 * security property. 196 */ removeFromDisabledTlsAlgs(String... algs)197 private static void removeFromDisabledTlsAlgs(String... algs) { 198 List<String> algList = Arrays.asList(algs); 199 String value = Security.getProperty("jdk.tls.disabledAlgorithms"); 200 StringBuilder newValue = new StringBuilder(); 201 for (String constraint : value.split(",")) { 202 String tmp = constraint.trim(); 203 if (!algList.contains(tmp)) { 204 newValue.append(tmp); 205 newValue.append(","); 206 } 207 } 208 Security.setProperty("jdk.tls.disabledAlgorithms", newValue.toString()); 209 } 210 } 211