3131import static org .junit .Assert .assertTrue ;
3232import static org .junit .Assume .assumeTrue ;
3333
34+ import java .io .BufferedReader ;
3435import java .io .IOException ;
36+ import java .io .InputStreamReader ;
37+ import java .io .OutputStream ;
38+ import java .io .PrintWriter ;
3539import java .lang .management .ClassLoadingMXBean ;
3640import java .lang .management .GarbageCollectorMXBean ;
3741import java .lang .management .ManagementFactory ;
4549import java .nio .file .Files ;
4650import java .nio .file .Path ;
4751import java .nio .file .attribute .PosixFilePermission ;
52+ import java .util .ArrayList ;
4853import java .util .HashMap ;
4954import java .util .List ;
5055import java .util .Map ;
5156import java .util .Set ;
57+ import java .util .concurrent .TimeUnit ;
58+ import java .util .stream .Collectors ;
5259
5360import javax .management .MBeanServer ;
5461import 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" );
0 commit comments