1 /* 2 * Copyright (c) 2015, 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.nio.file.Files; 25 import java.nio.file.Path; 26 import java.nio.file.Paths; 27 import java.security.KeyStore; 28 import java.security.cert.Certificate; 29 import java.security.cert.X509Certificate; 30 import java.util.LinkedHashMap; 31 import java.util.List; 32 import java.util.Map; 33 import java.util.Arrays; 34 import java.io.FileOutputStream; 35 import java.io.IOException; 36 import java.io.File; 37 import java.io.OutputStream; 38 import java.lang.module.ModuleDescriptor; 39 import sun.security.tools.keytool.CertAndKeyGen; 40 import sun.security.x509.X500Name; 41 import jdk.internal.module.ModuleInfoWriter; 42 import jdk.testlibrary.ProcessTools; 43 import jdk.testlibrary.OutputAnalyzer; 44 import jdk.testlibrary.JDKToolLauncher; 45 46 /** 47 * @test 48 * @bug 8130360 49 * @library /jdk/jigsaw/lib 50 * @library /lib/testlibrary 51 * @library /java/security/modules 52 * @summary Test custom JCE provider module with all possible modular condition. 53 * The test includes different combination of JCE client/provider 54 * modules interaction with or without service description. 55 * The different module types used here are, 56 * EXPLICIT - Modules have module descriptor(module-info.java) 57 * defining the module. 58 * AUTO - Are regular jar files but provided in MODULE_PATH 59 * instead of CLASS_PATH. 60 * UNNAMED - Are regular jar but provided through CLASS_PATH. 61 * This test uses a boolean argument indicating to use signed jar 62 * for the third party JCE provider. 63 * @run main/othervm -Duser.language=en -Duser.region=US JCEProviderModularTest 64 * false 65 * @run main/othervm -Duser.language=en -Duser.region=US JCEProviderModularTest 66 * true 67 */ 68 public class JCEProviderModularTest extends JigsawSecurityUtils { 69 70 private static final String TEST_SRC = System.getProperty("test.src"); 71 private static final Path SRC_DIR = Paths.get(TEST_SRC, "src"); 72 private static final String DESCRIPTOR = "metaservice"; 73 private static final String MODULAR = "modular"; 74 private static final String AUTO = "autodepend"; 75 private static final String JAR_EXTN = ".jar"; 76 77 private static final String SERVICE_MODULE_NAME = "jceprovidermodule"; 78 private static final Path SERVICE_SRC_DIR 79 = SRC_DIR.resolve(SERVICE_MODULE_NAME); 80 private static final String SERVICE_PKG = "provider"; 81 private static final String SERVICE_JAR_NAME = SERVICE_PKG + JAR_EXTN; 82 private static final String SERVICE_DESCRIPTOR_JAR_NAME 83 = SERVICE_PKG + DESCRIPTOR + JAR_EXTN; 84 private static final String MODULAR_SERVICE_JAR_NAME 85 = MODULAR + SERVICE_PKG + JAR_EXTN; 86 private static final String MODULE_SERVICE_DESCRIPTOR_JAR_NAME 87 = MODULAR + SERVICE_PKG + DESCRIPTOR + JAR_EXTN; 88 89 private static final String CLIENT_MODULE_NAME = "jceclientmodule"; 90 private static final Path CLIENT_SRC_DIR 91 = SRC_DIR.resolve(CLIENT_MODULE_NAME); 92 private static final String CLIENT_PKG = "client"; 93 private static final String CLIENT_JAR_NAME = CLIENT_PKG + JAR_EXTN; 94 private static final String MODULAR_CLIENT_AUTO_DEPEND_JAR_NAME 95 = MODULAR + CLIENT_PKG + AUTO + JAR_EXTN; 96 private static final String MODULAR_CLIENT_JAR_NAME 97 = MODULAR + CLIENT_PKG + JAR_EXTN; 98 99 private static final Path BUILD_DIR = Paths.get(".").resolve("build"); 100 private static final Path COMPILE_DIR = BUILD_DIR.resolve("bin"); 101 private static final Path SERVICE_BUILD_DIR 102 = COMPILE_DIR.resolve(SERVICE_PKG); 103 private static final Path SERVICE_META_BUILD_DIR 104 = COMPILE_DIR.resolve(SERVICE_PKG + DESCRIPTOR); 105 private static final Path CLIENT_BUILD_DIR 106 = COMPILE_DIR.resolve(CLIENT_PKG); 107 108 private static final String MODULE_DIR_NAME = "jarmodule"; 109 private static final Path MODULE_BASE_PATH 110 = BUILD_DIR.resolve(MODULE_DIR_NAME); 111 112 private static final Path ARTIFACTS_DIR = BUILD_DIR.resolve("artifacts"); 113 private static final Path SERVICE_ARTIFACTS_DIR 114 = ARTIFACTS_DIR.resolve(SERVICE_PKG); 115 private static final Path REGULAR_SERVICE_JAR 116 = SERVICE_ARTIFACTS_DIR.resolve(SERVICE_JAR_NAME); 117 private static final Path REGULAR_SERVICE_WITH_DESCRIPTOR_JAR 118 = SERVICE_ARTIFACTS_DIR.resolve(SERVICE_DESCRIPTOR_JAR_NAME); 119 private static final Path MODULAR_SERVICE_JAR 120 = SERVICE_ARTIFACTS_DIR.resolve(MODULAR_SERVICE_JAR_NAME); 121 private static final Path MODULAR_SERVICE_WITH_DESCRIPTOR_JAR 122 = SERVICE_ARTIFACTS_DIR.resolve(MODULE_SERVICE_DESCRIPTOR_JAR_NAME); 123 124 private static final Path CLIENT_ARTIFACTS_DIR 125 = ARTIFACTS_DIR.resolve(CLIENT_PKG); 126 private static final Path REGULAR_CLIENT_JAR 127 = CLIENT_ARTIFACTS_DIR.resolve(CLIENT_JAR_NAME); 128 private static final Path MODULAR_CLIENT_JAR 129 = CLIENT_ARTIFACTS_DIR.resolve(MODULAR_CLIENT_JAR_NAME); 130 private static final Path MODULAR_CLIENT_AUTO_DEPEND_JAR 131 = CLIENT_ARTIFACTS_DIR.resolve(MODULAR_CLIENT_AUTO_DEPEND_JAR_NAME); 132 133 private static final Path KEYSTORE_DIR = BUILD_DIR.resolve("store"); 134 private static final Path KEYSTORE_PATH 135 = KEYSTORE_DIR.resolve("test.keystore"); 136 private static final String STORE_PASSWORD = "password"; 137 private static final String ALIAS = "test"; 138 139 private static final String MAIN_CLASS = CLIENT_PKG + ".TestJCEClient"; 140 private static final String LOGIN_SERVICE_INTERFACE 141 = "java.security.Provider"; 142 private static final String SERVICE_IMPL = SERVICE_PKG + ".TestJCEProvider"; 143 private static final List<String> REQUIRED_MODULES 144 = Arrays.asList("java.base"); 145 private static final Path META_DESCRIPTOR = Paths.get("META-INF") 146 .resolve("services").resolve(LOGIN_SERVICE_INTERFACE); 147 private static final Path META_SERVICE_DESCRIPTOR 148 = SERVICE_META_BUILD_DIR.resolve(META_DESCRIPTOR); 149 150 private static final boolean WITH_SERVICE_DESCRIPTOR = true; 151 private static final boolean WITHOUT_SERVICE_DESCRIPTOR = false; 152 private static final boolean PASS = true; 153 private static final String PROVIDER_CLASS_NOT_FOUND_MSG 154 = "NoClassDefFoundError: provider/TestJCEProvider"; 155 private static final String PROVIDER_NOT_FOUND_BY_CLIENT_MSG 156 = "Unable to find Test JCE Provider"; 157 private static final String CAN_NOT_ACCESS_MSG = "cannot access class"; 158 private static final String NO_FAILURE = null; 159 private static final String USE_SERVICE_LOADER = "USE_SERVICE_LOADER"; 160 private static final String USE_CLASS_LOADER = "USE_CLASS_LOADER"; 161 private static final String USE_SECURITY_PROP = "USE_SECURITY_PROP"; 162 private static final List<String> MECHANISMS = Arrays.asList( 163 USE_SERVICE_LOADER, USE_CLASS_LOADER, USE_SECURITY_PROP); 164 private static final Path SECURITY_PROP_EXTN 165 = Paths.get("./java.security.extn"); 166 167 public static void main(String[] args) { 168 169 boolean success = true; 170 boolean useSignedJar = (args != null && args.length > 0) 171 ? Boolean.valueOf(args[0]) : false; 172 173 boolean ready = createArtifacts(useSignedJar); 174 if (!ready) { 175 throw new RuntimeException("Unable to prepare to run this test."); 176 } 177 178 for (String mechanism : MECHANISMS) { 179 boolean useClassLoader = USE_CLASS_LOADER.equals(mechanism); 180 boolean useServiceLoader = USE_SERVICE_LOADER.equals(mechanism); 181 //PARAMETER ORDERS - 182 //client Module Type, Service Module Type, 183 //Service META Descriptor Required, Expected Result, 184 //Expected Failure message, Signed/Unsigned?, 185 //mechanism used to find the provider 186 success &= runTest(MODULE_TYPE.EXPLICIT, MODULE_TYPE.EXPLICIT, 187 WITH_SERVICE_DESCRIPTOR, PASS, NO_FAILURE, 188 useSignedJar, mechanism); 189 success &= runTest(MODULE_TYPE.EXPLICIT, MODULE_TYPE.EXPLICIT, 190 WITHOUT_SERVICE_DESCRIPTOR, PASS, NO_FAILURE, 191 useSignedJar, mechanism); 192 success &= runTest(MODULE_TYPE.EXPLICIT, MODULE_TYPE.AUTO, 193 WITH_SERVICE_DESCRIPTOR, PASS, 194 ((useClassLoader) ? CAN_NOT_ACCESS_MSG : NO_FAILURE), 195 useSignedJar, mechanism); 196 success &= runTest(MODULE_TYPE.EXPLICIT, MODULE_TYPE.AUTO, 197 WITHOUT_SERVICE_DESCRIPTOR, PASS, 198 PROVIDER_CLASS_NOT_FOUND_MSG, useSignedJar, mechanism); 199 success &= runTest(MODULE_TYPE.EXPLICIT, MODULE_TYPE.UNNAMED, 200 WITH_SERVICE_DESCRIPTOR, PASS, 201 ((useClassLoader) ? CAN_NOT_ACCESS_MSG : NO_FAILURE), 202 useSignedJar, mechanism); 203 success &= runTest(MODULE_TYPE.EXPLICIT, MODULE_TYPE.UNNAMED, 204 WITHOUT_SERVICE_DESCRIPTOR, PASS, ((useClassLoader) 205 ? CAN_NOT_ACCESS_MSG 206 : ((useServiceLoader) 207 ? PROVIDER_NOT_FOUND_BY_CLIENT_MSG 208 : NO_FAILURE)), 209 useSignedJar, mechanism); 210 211 success &= runTest(MODULE_TYPE.AUTO, MODULE_TYPE.EXPLICIT, 212 WITH_SERVICE_DESCRIPTOR, PASS, NO_FAILURE, 213 useSignedJar, mechanism); 214 success &= runTest(MODULE_TYPE.AUTO, MODULE_TYPE.EXPLICIT, 215 WITHOUT_SERVICE_DESCRIPTOR, PASS, NO_FAILURE, 216 useSignedJar, mechanism); 217 success &= runTest(MODULE_TYPE.AUTO, MODULE_TYPE.AUTO, 218 WITH_SERVICE_DESCRIPTOR, PASS, NO_FAILURE, 219 useSignedJar, mechanism); 220 success &= runTest(MODULE_TYPE.AUTO, MODULE_TYPE.AUTO, 221 WITHOUT_SERVICE_DESCRIPTOR, PASS, 222 PROVIDER_CLASS_NOT_FOUND_MSG, useSignedJar, mechanism); 223 success &= runTest(MODULE_TYPE.AUTO, MODULE_TYPE.UNNAMED, 224 WITH_SERVICE_DESCRIPTOR, PASS, NO_FAILURE, 225 useSignedJar, mechanism); 226 success &= runTest(MODULE_TYPE.AUTO, MODULE_TYPE.UNNAMED, 227 WITHOUT_SERVICE_DESCRIPTOR, PASS, 228 ((useServiceLoader) ? PROVIDER_NOT_FOUND_BY_CLIENT_MSG 229 : NO_FAILURE), 230 useSignedJar, mechanism); 231 232 success &= runTest(MODULE_TYPE.UNNAMED, MODULE_TYPE.EXPLICIT, 233 WITH_SERVICE_DESCRIPTOR, PASS, NO_FAILURE, 234 useSignedJar, mechanism); 235 success &= runTest(MODULE_TYPE.UNNAMED, MODULE_TYPE.EXPLICIT, 236 WITHOUT_SERVICE_DESCRIPTOR, PASS, NO_FAILURE, 237 useSignedJar, mechanism); 238 success &= runTest(MODULE_TYPE.UNNAMED, MODULE_TYPE.AUTO, 239 WITH_SERVICE_DESCRIPTOR, PASS, NO_FAILURE, 240 useSignedJar, mechanism); 241 success &= runTest(MODULE_TYPE.UNNAMED, MODULE_TYPE.AUTO, 242 WITHOUT_SERVICE_DESCRIPTOR, PASS, 243 PROVIDER_CLASS_NOT_FOUND_MSG, useSignedJar, mechanism); 244 success &= runTest(MODULE_TYPE.UNNAMED, MODULE_TYPE.UNNAMED, 245 WITH_SERVICE_DESCRIPTOR, PASS, NO_FAILURE, 246 useSignedJar, mechanism); 247 success &= runTest(MODULE_TYPE.UNNAMED, MODULE_TYPE.UNNAMED, 248 WITHOUT_SERVICE_DESCRIPTOR, PASS, 249 ((useServiceLoader) ? PROVIDER_NOT_FOUND_BY_CLIENT_MSG 250 : NO_FAILURE), 251 useSignedJar, mechanism); 252 253 if (!success) { 254 throw new RuntimeException("At least one test failed."); 255 } 256 } 257 } 258 259 public static boolean runTest(MODULE_TYPE clientModuleType, 260 MODULE_TYPE serviceModuletype, boolean addMetaInfDescriptor, 261 boolean expectedResult, String expectedFailure, 262 boolean useSignedJar, String mechanism) { 263 264 boolean result = true; 265 try { 266 267 String testName = (clientModuleType + "_") 268 + (serviceModuletype + "_") 269 + ((addMetaInfDescriptor) ? "DESCRIPTOR" : "NO_DESCRIPTOR"); 270 271 System.out.println(String.format( 272 "Starting Test case: '%s'", testName)); 273 Path clientJarPath = findJarPath(false, clientModuleType, false, 274 (serviceModuletype == MODULE_TYPE.EXPLICIT)); 275 Path serviceJarPath = findJarPath( 276 true, serviceModuletype, addMetaInfDescriptor, false); 277 System.out.println(String.format( 278 "Client jar path : %s ", clientJarPath)); 279 System.out.println(String.format( 280 "Service jar path : %s ", serviceJarPath)); 281 //For automated/explicit module type copy the corresponding 282 //jars to module base folder, which will be considered as 283 //module base path during execution. 284 if (!(clientModuleType == MODULE_TYPE.UNNAMED 285 && serviceModuletype == MODULE_TYPE.UNNAMED)) { 286 copyJarsToModuleBase(clientModuleType, clientJarPath, 287 serviceModuletype, serviceJarPath); 288 } 289 290 System.out.println("Started executing java client with required" 291 + " custom JCE provider in class/module path."); 292 String moduleName 293 = getClientModuleName(clientModuleType, clientJarPath); 294 Path moduleBasePath = (clientModuleType != MODULE_TYPE.UNNAMED 295 || serviceModuletype != MODULE_TYPE.UNNAMED) 296 ? MODULE_BASE_PATH : null; 297 StringBuilder classPath 298 = getClassPath(clientModuleType, clientJarPath, 299 serviceModuletype, serviceJarPath); 300 301 final Map<String, String> VM_ARGS 302 = getVMArgs(mechanism, serviceModuletype); 303 OutputAnalyzer output = ProcessTools.executeTestJava( 304 getJavaCommand(moduleBasePath, classPath, moduleName, 305 MAIN_CLASS, VM_ARGS, mechanism)) 306 .outputTo(System.out) 307 .errorTo(System.out); 308 309 if (output.getExitValue() != 0) { 310 if (expectedFailure != null 311 && output.getOutput().contains(expectedFailure)) { 312 System.out.println("PASS: Test is expected to fail here."); 313 } else { 314 System.out.println(String.format( 315 "Unexpected failure occured during executing '%s'" 316 + " with exit code '%s'.", 317 MAIN_CLASS, output.getExitValue())); 318 result = false; 319 } 320 } 321 } catch (Exception e) { 322 e.printStackTrace(System.out); 323 result = false; 324 } finally { 325 //clean module path so that the modulepath can only hold 326 //the required jars for next run. 327 cleanModuleBasePath(); 328 } 329 330 return (expectedResult == result); 331 } 332 333 //Decide the pre-generated client/service jar path for a given module type. 334 private static Path findJarPath(boolean service, MODULE_TYPE moduleType, 335 boolean addMetaInfDescriptor, boolean dependsOnServiceModule) { 336 if (service) { 337 if (moduleType == MODULE_TYPE.EXPLICIT) { 338 if (addMetaInfDescriptor) { 339 return MODULAR_SERVICE_WITH_DESCRIPTOR_JAR; 340 } else { 341 return MODULAR_SERVICE_JAR; 342 } 343 } else { 344 if (addMetaInfDescriptor) { 345 return REGULAR_SERVICE_WITH_DESCRIPTOR_JAR; 346 } else { 347 return REGULAR_SERVICE_JAR; 348 } 349 } 350 } else { 351 if (moduleType == MODULE_TYPE.EXPLICIT) { 352 if (dependsOnServiceModule) { 353 return MODULAR_CLIENT_JAR; 354 } else { 355 return MODULAR_CLIENT_AUTO_DEPEND_JAR; 356 } 357 } else { 358 return REGULAR_CLIENT_JAR; 359 } 360 } 361 } 362 363 //Copy pre-generated jar files to the base module path based on module type. 364 private static void copyJarsToModuleBase(MODULE_TYPE clientModuleType, 365 Path modularClientJarPath, MODULE_TYPE serviceModuletype, 366 Path modularServiceJarPath) throws IOException { 367 368 if (MODULE_BASE_PATH != null) { 369 Files.createDirectories(MODULE_BASE_PATH); 370 } 371 if (clientModuleType != MODULE_TYPE.UNNAMED) { 372 Path clientArtifactName = MODULE_BASE_PATH.resolve( 373 modularClientJarPath.getFileName()); 374 System.out.println(String.format("Copy client jar path: '%s'" 375 + " to module base path: %s", modularClientJarPath, 376 clientArtifactName)); 377 Files.copy(modularClientJarPath, clientArtifactName); 378 } 379 if (serviceModuletype != MODULE_TYPE.UNNAMED) { 380 Path serviceArtifactName = MODULE_BASE_PATH.resolve( 381 modularServiceJarPath.getFileName()); 382 System.out.println(String.format("Copy service jar path: '%s'" 383 + " to module base path: %s", modularServiceJarPath, 384 serviceArtifactName)); 385 Files.copy(modularServiceJarPath, serviceArtifactName); 386 } 387 } 388 389 //Pre-compile and generate the artifacts required to run this test. 390 private static boolean createArtifacts(boolean useSignedJar) { 391 392 boolean done = true; 393 try { 394 //If signed jar required then prepare the keystore for first time. 395 if (useSignedJar) { 396 done &= generateKeyStore(KEYSTORE_PATH.toString(), 397 STORE_PASSWORD, ALIAS); 398 } 399 done &= CompilerUtils.compile(SERVICE_SRC_DIR, SERVICE_BUILD_DIR); 400 done &= CompilerUtils.compile(SERVICE_SRC_DIR, 401 SERVICE_META_BUILD_DIR); 402 done &= createMetaInfServiceDescriptor(META_SERVICE_DESCRIPTOR, 403 SERVICE_IMPL); 404 //Generate regular/modular jars with(out) META-INF 405 //service descriptor 406 generateJar(true, MODULE_TYPE.EXPLICIT, MODULAR_SERVICE_JAR, 407 SERVICE_BUILD_DIR, false, useSignedJar); 408 generateJar(true, MODULE_TYPE.EXPLICIT, 409 MODULAR_SERVICE_WITH_DESCRIPTOR_JAR, 410 SERVICE_META_BUILD_DIR, false, useSignedJar); 411 generateJar(true, MODULE_TYPE.UNNAMED, REGULAR_SERVICE_JAR, 412 SERVICE_BUILD_DIR, false, useSignedJar); 413 generateJar(true, MODULE_TYPE.UNNAMED, 414 REGULAR_SERVICE_WITH_DESCRIPTOR_JAR, 415 SERVICE_META_BUILD_DIR, false, useSignedJar); 416 //Generate regular/modular(depends on explicit/auto service) 417 //jars for client 418 done &= CompilerUtils.compile(CLIENT_SRC_DIR, CLIENT_BUILD_DIR, 419 "-cp", REGULAR_SERVICE_JAR.toRealPath().toString()); 420 generateJar(false, MODULE_TYPE.EXPLICIT, MODULAR_CLIENT_JAR, 421 CLIENT_BUILD_DIR, true, useSignedJar); 422 generateJar(false, MODULE_TYPE.EXPLICIT, 423 MODULAR_CLIENT_AUTO_DEPEND_JAR, CLIENT_BUILD_DIR, 424 false, useSignedJar); 425 generateJar(false, MODULE_TYPE.UNNAMED, 426 REGULAR_CLIENT_JAR, CLIENT_BUILD_DIR, false, useSignedJar); 427 428 System.out.println(String.format( 429 "Artifacts generated successfully? '%s'", done)); 430 } catch (IOException e) { 431 e.printStackTrace(System.out); 432 done = false; 433 } 434 return done; 435 } 436 437 //Generate modular/regular jar based on module type. 438 private static void generateJar(boolean service, MODULE_TYPE moduleType, 439 Path jarFile, Path compilePath, boolean depends, 440 boolean useSignedJar) throws IOException { 441 442 ModuleDescriptor moduleDescriptor = null; 443 if (service) { 444 moduleDescriptor = generateModuleDescriptor(service, moduleType, 445 SERVICE_MODULE_NAME, SERVICE_PKG, 446 LOGIN_SERVICE_INTERFACE, SERVICE_IMPL, null, 447 REQUIRED_MODULES, depends); 448 } else { 449 moduleDescriptor = generateModuleDescriptor(service, 450 moduleType, CLIENT_MODULE_NAME, CLIENT_PKG, 451 LOGIN_SERVICE_INTERFACE, null, SERVICE_MODULE_NAME, 452 REQUIRED_MODULES, depends); 453 } 454 System.out.println(String.format( 455 "Creating jar file '%s'", jarFile)); 456 JarUtils.createJarFile(jarFile, compilePath); 457 if (moduleDescriptor != null) { 458 Path dir = Files.createTempDirectory("tmp"); 459 Path mi = dir.resolve("module-info.class"); 460 try (OutputStream out = Files.newOutputStream(mi)) { 461 ModuleInfoWriter.write(moduleDescriptor, out); 462 } 463 System.out.println(String.format( 464 "Adding 'module-info.class' to jar file '%s'", jarFile)); 465 JarUtils.updateJarFile(jarFile, dir); 466 } 467 //If the jar holds provider implementation then sign it. 468 if (service && useSignedJar) { 469 signJar(jarFile, KEYSTORE_PATH.toRealPath().toString(), 470 STORE_PASSWORD, ALIAS); 471 } 472 } 473 474 //Construct class path argument value. 475 private static StringBuilder getClassPath(MODULE_TYPE clientModuleType, 476 Path clientJarPath, MODULE_TYPE serviceModuletype, 477 Path serviceJarPath) throws IOException { 478 479 StringBuilder classPath = new StringBuilder(); 480 classPath.append((clientModuleType == MODULE_TYPE.UNNAMED) 481 ? (clientJarPath.toRealPath().toString() 482 + File.pathSeparatorChar) : ""); 483 classPath.append((serviceModuletype == MODULE_TYPE.UNNAMED) 484 ? serviceJarPath.toRealPath().toString() : ""); 485 return classPath; 486 } 487 488 //Construct client modulename to run the client. It is fixed for explicit 489 //module type while it is same as jar file name for automated module type. 490 private static String getClientModuleName(MODULE_TYPE clientModuleType, 491 Path clientJarPath) { 492 493 String jarFileName = clientJarPath.toFile().getName(); 494 return (clientModuleType == MODULE_TYPE.EXPLICIT) 495 ? CLIENT_MODULE_NAME 496 : ((clientModuleType == MODULE_TYPE.AUTO) 497 ? jarFileName.substring( 498 0, jarFileName.indexOf(JAR_EXTN)) : ""); 499 } 500 501 //Delete all the files inside the base module path. 502 private static void cleanModuleBasePath() { 503 504 Arrays.asList(MODULE_BASE_PATH.toFile().listFiles()) 505 .forEach(f -> { 506 System.out.println("delete " + f); 507 f.delete(); 508 }); 509 System.out.println("------------------------------------------------"); 510 } 511 512 //Generate a keystore with random keys. 513 public static boolean generateKeyStore(String keyStoreFile, 514 String password, String alias) throws IOException { 515 boolean created = true; 516 Path parent = KEYSTORE_PATH.getParent(); 517 if (parent != null) { 518 Files.createDirectories(parent); 519 } 520 try (FileOutputStream keyStoreOut 521 = new FileOutputStream(keyStoreFile)) { 522 523 KeyStore keyStore = KeyStore.getInstance("JKS"); 524 keyStore.load(null, null); 525 526 CertAndKeyGen keyGen 527 = new CertAndKeyGen("RSA", "SHA1WithRSA", null); 528 keyGen.generate(2048); 529 //Generate self signed certificate 530 Certificate[] chain = new X509Certificate[1]; 531 chain[0] = keyGen.getSelfCertificate( 532 new X500Name("CN=ROOT"), (long) 365 * 24 * 3600); 533 keyStore.setKeyEntry(alias, keyGen.getPrivateKey(), 534 password.toCharArray(), chain); 535 536 keyStore.store(keyStoreOut, password.toCharArray()); 537 } catch (Exception e) { 538 created = false; 539 e.printStackTrace(System.out); 540 } 541 return created; 542 } 543 544 //Sign a jar file by provided keystore file. 545 public static void signJar(Path jarFile, String keyStore, 546 String password, String alias) { 547 try { 548 JDKToolLauncher jarsigner = JDKToolLauncher.create("jarsigner") 549 .addToolArg("-keystore") 550 .addToolArg(keyStore) 551 .addToolArg("-storepass") 552 .addToolArg(password) 553 .addToolArg("-keypass") 554 .addToolArg(password) 555 .addToolArg(jarFile.toFile().getCanonicalPath()) 556 .addToolArg(alias); 557 ProcessBuilder processBuilder 558 = new ProcessBuilder(jarsigner.getCommand()); 559 OutputAnalyzer output = ProcessTools.executeProcess(processBuilder); 560 System.out.println( 561 "_________________BEGIN JAR SIGN OUTPUT__________________"); 562 System.out.println(output.getOutput()); 563 System.out.println( 564 "_______________________END OUTPUT_______________________"); 565 output.shouldHaveExitValue(0); 566 } catch (Exception e) { 567 throw new RuntimeException(String.format( 568 "Unable to sign Jar file '%s'", jarFile)); 569 } 570 } 571 572 private static Map<String, String> getVMArgs(String mechanism, 573 MODULE_TYPE serviceModuletype) throws IOException { 574 final Map<String, String> VM_ARGS = new LinkedHashMap<>(); 575 VM_ARGS.put("-Duser.language=", "en"); 576 VM_ARGS.put("-Duser.region=", "US"); 577 //If mechanism to find the provider through Security.getProvider() 578 //then use providerName/ProviderClassName based on modular/regular 579 //provider jar in "java.security" configuration file. 580 if (USE_SECURITY_PROP.equals(mechanism)) { 581 if (serviceModuletype == MODULE_TYPE.UNNAMED) { 582 Files.write(SECURITY_PROP_EXTN, 583 "security.provider.10=provider.TestJCEProvider" 584 .getBytes()); 585 } else { 586 Files.write(SECURITY_PROP_EXTN, 587 "security.provider.10=TEST".getBytes()); 588 } 589 VM_ARGS.put("-Djava.security.properties=", 590 SECURITY_PROP_EXTN.toFile().getCanonicalPath()); 591 } 592 return VM_ARGS; 593 } 594 595 }