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.io.File;
  25 import java.nio.file.Files;
  26 import java.nio.file.Paths;
  27 import java.security.AccessControlException;
  28 import java.security.AccessController;
  29 import java.security.Permission;
  30 import java.security.PrivilegedAction;
  31 import jdk.test.lib.process.ProcessTools;
  32 
  33 /**
  34  * @test
  35  * @bug 8048360
  36  * @summary test policy entry with signedBy alias
  37  * @library /test/lib
  38  * @run main/othervm SignedJarTest
  39  */
  40 public class SignedJarTest {
  41 
  42     private static final String FS = File.separator;
  43     private static final String JAVA_HOME = System.getProperty("test.jdk");
  44     private static final String TESTCLASSES = System.getProperty("test.classes", "");
  45     private static final String TESTSRC = System.getProperty("test.src", "");
  46     private static final String KEYTOOL = JAVA_HOME + FS + "bin" + FS + "keytool";
  47     private static final String JAR = JAVA_HOME + FS + "bin" + FS + "jar";
  48     private static final String JARSIGNER = JAVA_HOME + FS + "bin" + FS + "jarsigner";
  49     private static final String PASSWORD = "password";
  50     private static final String PWDFILE = "keypass";
  51     private static final String POLICY1 = "SignedJarTest_1.policy";
  52     private static final String POLICY2 = "SignedJarTest_2.policy";
  53     private static final String KEYSTORE1 = "both.jks";
  54     private static final String KEYSTORE2 = "first.jks";
  55 
  56     public static void main(String args[]) throws Throwable {
  57         //copy PrivilegeTest.class, policy files and keystore password file into current direcotry
  58         Files.copy(Paths.get(TESTCLASSES, "PrivilegeTest.class"), Paths.get("PrivilegeTest.class"));
  59         Files.copy(Paths.get(TESTSRC, POLICY1), Paths.get(POLICY1));
  60         Files.copy(Paths.get(TESTSRC, POLICY2), Paths.get(POLICY2));
  61         Files.copy(Paths.get(TESTSRC, PWDFILE), Paths.get(PWDFILE));
  62 
  63         //create Jar file
  64         ProcessTools.executeCommand(JAR, "-cvf", "test.jar", "PrivilegeTest.class");
  65 
  66         //Creating first key , keystore both.jks
  67         ProcessTools.executeCommand(KEYTOOL,
  68                 "-genkey",
  69                 "-alias", "first",
  70                 "-keystore", KEYSTORE1,
  71                 "-keypass", PASSWORD,
  72                 "-dname", "cn=First",
  73                 "-storepass", PASSWORD
  74         ).shouldHaveExitValue(0);
  75 
  76         //Creating Second key, keystore both.jks
  77         ProcessTools.executeCommand(KEYTOOL,
  78                 "-genkey",
  79                 // "-storetype","JKS",
  80                 "-alias", "second",
  81                 "-keystore", KEYSTORE1,
  82                 "-keypass", PASSWORD,
  83                 "-dname", "cn=Second",
  84                 "-storepass", PASSWORD
  85         ).shouldHaveExitValue(0);
  86 
  87         //copy both.jks to first.jks, remove second Keypair from first.jks
  88         Files.copy(Paths.get(KEYSTORE1), Paths.get(KEYSTORE2));
  89         ProcessTools.executeCommand(KEYTOOL,
  90                 "-delete",
  91                 "-keystore", KEYSTORE2,
  92                 "-alias", "second",
  93                 "-storepass", PASSWORD
  94         ).shouldHaveExitValue(0);
  95 
  96         //sign jar with first key, first.jar is only signed by first signer
  97         ProcessTools.executeCommand(JARSIGNER,
  98                 "-keystore", KEYSTORE1,
  99                 "-storepass", PASSWORD,
 100                 "-keypass", PASSWORD,
 101                 "-signedjar", "first.jar", "test.jar",
 102                 "first").shouldHaveExitValue(0);
 103 
 104         //sign jar with second key, both.jar is signed by first and second signer
 105         ProcessTools.executeCommand(JARSIGNER,
 106                 "-keystore", KEYSTORE1,
 107                 "-storepass", PASSWORD,
 108                 "-keypass", PASSWORD,
 109                 "-signedjar", "both.jar", "first.jar",
 110                 "second").shouldHaveExitValue(0);
 111 
 112         //test case 1
 113         //setIO permission granted to code that was signed by first signer
 114         //setFactory permission granted to code that was signed by second signer
 115         //Keystore that contains both first and second  keypairs
 116         //code was singed by first signer
 117         //Expect AccessControlException for setFactory permission
 118         System.out.println("Test Case 1");
 119         //copy policy file into current directory
 120         String[] cmd = constructCMD("first.jar", POLICY1, "false", "true");
 121         ProcessTools.executeTestJvm(cmd).shouldHaveExitValue(0);
 122 
 123         //test case 2, test with both.jar
 124         //setIO permission granted to code that was signed by first signer
 125         //setFactory permission granted to code that was signed by second signer
 126         //Keystore that contains both first and second  keypairs
 127         //code was singed by first signer and second signer
 128         //Expect no AccessControlException
 129         System.out.println("Test Case 2");
 130         cmd = constructCMD("both.jar", POLICY1, "false", "false");
 131         ProcessTools.executeTestJvm(cmd).shouldHaveExitValue(0);
 132 
 133         //test case 3
 134         //setIO permission granted to code that was signed by first signer
 135         //setFactory permission granted to code that was signed by second signer
 136         //Keystore that contains only first keypairs
 137         //code was singed by first signer and second signer
 138         //Expect AccessControlException for setFactory permission
 139         System.out.println("Test Case 3");
 140         cmd = constructCMD("both.jar", POLICY2, "false", "true");
 141         ProcessTools.executeTestJvm(cmd).shouldHaveExitValue(0);
 142 
 143     }
 144 
 145     private static String[] constructCMD(String classpath, String policy, String arg1, String arg2) {
 146         String[] cmd = {
 147             "-classpath", classpath,
 148             "-Djava.security.manager",
 149             "-Djava.security.policy=" + policy,
 150             "PrivilegeTest",
 151             arg1, arg2};
 152         return cmd;
 153     }
 154 }
 155 
 156 class PrivilegeTest {
 157 
 158     private static final Permission PERM1 = new RuntimePermission("setIO");
 159     private static final Permission PERM2 = new RuntimePermission("setFactory");
 160 
 161     public static void main(String args[]) {
 162         boolean expectException1 = Boolean.parseBoolean(args[0]);
 163         boolean expectException2 = Boolean.parseBoolean(args[1]);
 164         test(PERM1, expectException1);
 165         test(PERM2, expectException2);
 166     }
 167 
 168     public static void test(Permission perm, boolean expectException) {
 169         boolean getException = (Boolean) AccessController.doPrivileged((PrivilegedAction) () -> {
 170             try {
 171                 AccessController.checkPermission(perm);
 172                 return (Boolean) false;
 173             } catch (AccessControlException ex) {
 174                 return (Boolean) true;
 175             }
 176         });
 177 
 178         if (expectException ^ getException) {
 179             String message = "Check Permission :" + perm + "\n ExpectException = "
 180                     + expectException + "\n getException = " + getException;
 181             throw new RuntimeException(message);
 182         }
 183 
 184     }
 185 
 186 }