Skip to content

Commit 27dd37c

Browse files
Use keytool from java in the temp directory.
1 parent 22aa02b commit 27dd37c

File tree

5 files changed

+80
-4
lines changed

5 files changed

+80
-4
lines changed

substratevm/src/com.oracle.svm.test/src/com/oracle/svm/test/jmx/JmxTest.java

Lines changed: 76 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -31,7 +31,11 @@
3131
import static org.junit.Assert.assertTrue;
3232
import static org.junit.Assume.assumeTrue;
3333

34+
import java.io.BufferedReader;
3435
import java.io.IOException;
36+
import java.io.InputStreamReader;
37+
import java.io.OutputStream;
38+
import java.io.PrintWriter;
3539
import java.lang.management.ClassLoadingMXBean;
3640
import java.lang.management.GarbageCollectorMXBean;
3741
import java.lang.management.ManagementFactory;
@@ -45,10 +49,13 @@
4549
import java.nio.file.Files;
4650
import java.nio.file.Path;
4751
import java.nio.file.attribute.PosixFilePermission;
52+
import java.util.ArrayList;
4853
import java.util.HashMap;
4954
import java.util.List;
5055
import java.util.Map;
5156
import java.util.Set;
57+
import java.util.concurrent.TimeUnit;
58+
import java.util.stream.Collectors;
5259

5360
import javax.management.MBeanServer;
5461
import javax.management.MBeanServerConnection;
@@ -100,17 +107,20 @@ public static void setup() throws IOException {
100107
System.setProperty(SSL_PROPERTY, TRUE);
101108
System.setProperty(REGISTRY_SSL_PROPERTY, TRUE);
102109

103-
// Copy resources into tempDirectory
104110
Path tempDirectory = Files.createTempDirectory("jmxtest");
111+
112+
// Generate SSL keystore, client cert, and truststore
113+
createClientKey(tempDirectory);
114+
createClientCert(tempDirectory);
115+
createServerTrustStore(tempDirectory);
116+
// Copy resources into tempDirectory
105117
Path jmxRemoteAccess = tempDirectory.resolve("jmxremote.access");
106118
Path jmxRemotePassword = tempDirectory.resolve("jmxremote.password");
107119
Path clientkeystore = tempDirectory.resolve("clientkeystore");
108120
Path servertruststore = tempDirectory.resolve("servertruststore");
109121
// Note: full paths are used to ensure analysis includes the resources automatically
110122
Files.copy(JmxTest.class.getResourceAsStream("/resources/jmxremote/jmxremote.access"), jmxRemoteAccess);
111123
Files.copy(JmxTest.class.getResourceAsStream("/resources/jmxremote/jmxremote.password"), jmxRemotePassword);
112-
Files.copy(JmxTest.class.getResourceAsStream("/resources/jmxremote/clientkeystore"), clientkeystore);
113-
Files.copy(JmxTest.class.getResourceAsStream("/resources/jmxremote/servertruststore"), servertruststore);
114124

115125
// The following are dummy password and access files required for testing authentication.
116126
System.setProperty(ACCESS_PROPERTY, jmxRemoteAccess.toString());
@@ -137,6 +147,69 @@ public static void setup() throws IOException {
137147
}
138148
}
139149

150+
private static void createClientKey(Path tempDirectory) throws IOException {
151+
final List<String> commandParameters = new ArrayList<>(List.of("keytool", "-genkey"));
152+
commandParameters.addAll(List.of("-keystore", "clientkeystore"));
153+
commandParameters.addAll(List.of("-alias", "clientkey"));
154+
commandParameters.addAll(List.of("-storepass", "clientpass"));
155+
commandParameters.addAll(List.of("-keypass", "clientpass"));
156+
commandParameters.addAll(List.of("-dname", "CN=test, OU=test, O=test, L=test, ST=test, C=test, EMAILADDRESS=test"));
157+
commandParameters.addAll(List.of("-validity", "99999"));
158+
commandParameters.addAll(List.of("-keyalg", "rsa"));
159+
160+
ProcessBuilder pb = new ProcessBuilder().command(commandParameters);
161+
pb.directory(tempDirectory.toFile());
162+
final Process process = pb.start();
163+
waitForProcess(process, commandParameters);
164+
}
165+
166+
private static void createClientCert(Path tempDirectory) throws IOException {
167+
final List<String> commandParameters = new ArrayList<>(List.of("keytool", "-exportcert"));
168+
commandParameters.addAll(List.of("-keystore", "clientkeystore"));
169+
commandParameters.addAll(List.of("-alias", "clientkey"));
170+
commandParameters.addAll(List.of("-storepass", "clientpass"));
171+
commandParameters.addAll(List.of("-file", "client.cer"));
172+
173+
ProcessBuilder pb = new ProcessBuilder().command(commandParameters);
174+
pb.directory(tempDirectory.toFile());
175+
final Process process = pb.start();
176+
waitForProcess(process, commandParameters);
177+
}
178+
179+
private static void createServerTrustStore(Path tempDirectory) throws IOException {
180+
final List<String> commandParameters = new ArrayList<>(List.of("keytool", "-importcert"));
181+
commandParameters.addAll(List.of("-file", "client.cer"));
182+
commandParameters.addAll(List.of("-keystore", "servertruststore"));
183+
commandParameters.addAll(List.of("-storepass", "servertrustpass"));
184+
185+
ProcessBuilder pb = new ProcessBuilder().command(commandParameters);
186+
pb.directory(tempDirectory.toFile());
187+
final Process process = pb.start();
188+
// Prompted about whether the cert should be trusted.
189+
OutputStream os = process.getOutputStream();
190+
PrintWriter writer = new PrintWriter(os);
191+
writer.write("y\n");
192+
writer.flush();
193+
waitForProcess(process, commandParameters);
194+
}
195+
196+
private static void waitForProcess(Process process, List<String> command) throws IOException {
197+
try {
198+
process.waitFor(5, TimeUnit.SECONDS);
199+
} catch (InterruptedException e) {
200+
throw new IOException("Keytool execution error");
201+
}
202+
203+
if (process.exitValue() > 0) {
204+
final String processError = (new BufferedReader(new InputStreamReader(process.getErrorStream()))).lines()
205+
.collect(Collectors.joining(" \\ "));
206+
final String processOutput = (new BufferedReader(new InputStreamReader(process.getInputStream()))).lines()
207+
.collect(Collectors.joining(" \\ "));
208+
throw new IOException(
209+
"Keytool execution error: " + processError + ", output: " + processOutput + ", command: " + command);
210+
}
211+
}
212+
140213
private static MBeanServerConnection getLocalMBeanServerConnectionStatic() {
141214
try {
142215
JMXServiceURL jmxUrl = new JMXServiceURL("service:jmx:rmi:///jndi/rmi://" + "localhost" + ":" + TEST_PORT + "/jmxrmi");

substratevm/src/com.oracle.svm.test/src/resources/jmxremote/README.md

Lines changed: 4 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -7,7 +7,10 @@ Create the file `jmxremote.access`. In it add the line: `myrole readwrite`. This
77
Next, create the file `jmxremote.password`. In it add the line: `myrole MYP@SSWORD`. This specifies a password for the previously created role. This password will automatically be hashed and updated in the file once the first connection is made. No further action is needed.
88

99
### SSL
10-
Make the client keystore and client key.
10+
The remote JMX unit test automatically generates the necessary files in a temporary directory.
11+
However, these are the steps to generate them manually:
12+
13+
Make the client keystore and client key.
1114
```
1215
keytool -genkeypair -keystore clientkeystore -alias clientkey -validity 99999 -storepass clientpass -keypass clientpass -keyalg rsa
1316
```
Binary file not shown.
Binary file not shown.
Binary file not shown.

0 commit comments

Comments
 (0)