1 /* 2 * Copyright (c) 2015, 2016, 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 /** 25 * @test 26 * @bug 8056174 27 * @summary Make sure JarSigner impl conforms to spec 28 * @library /lib/testlibrary 29 * @modules java.base/sun.security.tools.keytool 30 * java.base/sun.security.provider.certpath 31 * jdk.jartool 32 * jdk.crypto.ec 33 */ 34 35 import com.sun.jarsigner.ContentSigner; 36 import com.sun.jarsigner.ContentSignerParameters; 37 import jdk.security.jarsigner.JarSigner; 38 import jdk.testlibrary.JarUtils; 39 import sun.security.provider.certpath.X509CertPath; 40 41 import java.io.File; 42 import java.io.IOException; 43 import java.net.URI; 44 import java.nio.file.Files; 45 import java.nio.file.Paths; 46 import java.security.*; 47 import java.security.cert.CertPath; 48 import java.security.cert.CertificateException; 49 import java.security.cert.CertificateFactory; 50 import java.util.Arrays; 51 import java.util.Collections; 52 import java.util.function.BiConsumer; 53 54 public class Spec { 55 56 public static void main(String[] args) throws Exception { 57 58 // Prepares raw file 59 Files.write(Paths.get("a"), "a".getBytes()); 60 61 // Pack 62 JarUtils.createJar("a.jar", "a"); 63 64 // Prepare a keystore 65 sun.security.tools.keytool.Main.main( 66 ("-keystore ks -storepass changeit -keypass changeit -dname" + 67 " CN=RSA -alias r -genkeypair -keyalg rsa").split(" ")); 68 sun.security.tools.keytool.Main.main( 69 ("-keystore ks -storepass changeit -keypass changeit -dname" + 70 " CN=DSA -alias d -genkeypair -keyalg dsa").split(" ")); 71 72 char[] pass = "changeit".toCharArray(); 73 74 KeyStore ks = KeyStore.getInstance( 75 new File("ks"), pass); 76 PrivateKey pkr = (PrivateKey)ks.getKey("r", pass); 77 PrivateKey pkd = (PrivateKey)ks.getKey("d", pass); 78 CertPath cp = CertificateFactory.getInstance("X.509") 79 .generateCertPath(Arrays.asList(ks.getCertificateChain("r"))); 80 81 Provider sun = Security.getProvider("SUN"); 82 83 // throws 84 npe(()->new JarSigner.Builder(null)); 85 npe(()->new JarSigner.Builder(null, cp)); 86 iae(()->new JarSigner.Builder( 87 pkr, new X509CertPath(Collections.emptyList()))); 88 iae(()->new JarSigner.Builder(pkd, cp)); // unmatched certs alg 89 90 JarSigner.Builder b1 = new JarSigner.Builder(pkr, cp); 91 92 npe(()->b1.digestAlgorithm(null)); 93 nsae(()->b1.digestAlgorithm("HAHA")); 94 b1.digestAlgorithm("SHA-256"); 95 96 npe(()->b1.digestAlgorithm("SHA-256", null)); 97 npe(()->b1.digestAlgorithm(null, sun)); 98 nsae(()->b1.digestAlgorithm("HAHA", sun)); 99 b1.digestAlgorithm("SHA-256", sun); 100 101 npe(()->b1.signatureAlgorithm(null)); 102 nsae(()->b1.signatureAlgorithm("HAHAwithHEHE")); 103 iae(()->b1.signatureAlgorithm("SHA256withECDSA")); 104 105 npe(()->b1.signatureAlgorithm(null, sun)); 106 npe(()->b1.signatureAlgorithm("SHA256withRSA", null)); 107 nsae(()->b1.signatureAlgorithm("HAHAwithHEHE", sun)); 108 iae(()->b1.signatureAlgorithm("SHA256withDSA", sun)); 109 110 npe(()->b1.tsa(null)); 111 112 npe(()->b1.signerName(null)); 113 iae(()->b1.signerName("")); 114 iae(()->b1.signerName("123456789")); 115 iae(()->b1.signerName("a+b")); 116 117 npe(()->b1.setProperty(null, "")); 118 uoe(()->b1.setProperty("what", "")); 119 npe(()->b1.setProperty("tsadigestalg", null)); 120 iae(()->b1.setProperty("tsadigestalg", "HAHA")); 121 npe(()->b1.setProperty("tsapolicyid", null)); 122 npe(()->b1.setProperty("internalsf", null)); 123 iae(()->b1.setProperty("internalsf", "Hello")); 124 npe(()->b1.setProperty("sectionsonly", null)); 125 iae(()->b1.setProperty("sectionsonly", "OK")); 126 npe(()->b1.setProperty("altsigner", null)); 127 npe(()->b1.eventHandler(null)); 128 129 // default values 130 JarSigner.Builder b2 = new JarSigner.Builder(pkr, cp); 131 JarSigner js2 = b2.build(); 132 133 assertTrue(js2.getDigestAlgorithm().equals( 134 JarSigner.Builder.getDefaultDigestAlgorithm())); 135 assertTrue(js2.getSignatureAlgorithm().equals( 136 JarSigner.Builder.getDefaultSignatureAlgorithm(pkr))); 137 assertTrue(js2.getTsa() == null); 138 assertTrue(js2.getSignerName().equals("SIGNER")); 139 assertTrue(js2.getProperty("tsadigestalg").equals( 140 JarSigner.Builder.getDefaultDigestAlgorithm())); 141 assertTrue(js2.getProperty("tsapolicyid") == null); 142 assertTrue(js2.getProperty("internalsf").equals("false")); 143 assertTrue(js2.getProperty("sectionsonly").equals("false")); 144 assertTrue(js2.getProperty("altsigner") == null); 145 uoe(()->js2.getProperty("invalid")); 146 147 // default values 148 BiConsumer<String,String> myeh = (a,s)->{}; 149 URI tsa = new URI("https://tsa.com"); 150 151 JarSigner.Builder b3 = new JarSigner.Builder(pkr, cp) 152 .digestAlgorithm("SHA-1") 153 .signatureAlgorithm("SHA1withRSA") 154 .signerName("Duke") 155 .tsa(tsa) 156 .setProperty("tsadigestalg", "SHA-512") 157 .setProperty("tsapolicyid", "1.2.3.4") 158 .setProperty("internalsf", "true") 159 .setProperty("sectionsonly", "true") 160 .setProperty("altsigner", "MyContentSigner") 161 .eventHandler(myeh); 162 JarSigner js3 = b3.build(); 163 164 assertTrue(js3.getDigestAlgorithm().equals("SHA-1")); 165 assertTrue(js3.getSignatureAlgorithm().equals("SHA1withRSA")); 166 assertTrue(js3.getTsa().equals(tsa)); 167 assertTrue(js3.getSignerName().equals("DUKE")); 168 assertTrue(js3.getProperty("tsadigestalg").equals("SHA-512")); 169 assertTrue(js3.getProperty("tsapolicyid").equals("1.2.3.4")); 170 assertTrue(js3.getProperty("internalsf").equals("true")); 171 assertTrue(js3.getProperty("sectionsonly").equals("true")); 172 assertTrue(js3.getProperty("altsigner").equals("MyContentSigner")); 173 assertTrue(js3.getProperty("altsignerpath") == null); 174 175 assertTrue(JarSigner.Builder.getDefaultDigestAlgorithm().equals("SHA-256")); 176 177 // Calculating large DSA and RSA keys are too slow. 178 KeyPairGenerator kpg = KeyPairGenerator.getInstance("RSA"); 179 kpg.initialize(1024); 180 assertTrue(JarSigner.Builder 181 .getDefaultSignatureAlgorithm(kpg.generateKeyPair().getPrivate()) 182 .equals("SHA256withRSA")); 183 184 kpg = KeyPairGenerator.getInstance("DSA"); 185 kpg.initialize(1024); 186 assertTrue(JarSigner.Builder 187 .getDefaultSignatureAlgorithm(kpg.generateKeyPair().getPrivate()) 188 .equals("SHA256withDSA")); 189 190 kpg = KeyPairGenerator.getInstance("EC"); 191 kpg.initialize(192); 192 assertTrue(JarSigner.Builder 193 .getDefaultSignatureAlgorithm(kpg.generateKeyPair().getPrivate()) 194 .equals("SHA256withECDSA")); 195 kpg.initialize(384); 196 assertTrue(JarSigner.Builder 197 .getDefaultSignatureAlgorithm(kpg.generateKeyPair().getPrivate()) 198 .equals("SHA384withECDSA")); 199 kpg.initialize(571); 200 assertTrue(JarSigner.Builder 201 .getDefaultSignatureAlgorithm(kpg.generateKeyPair().getPrivate()) 202 .equals("SHA512withECDSA")); 203 } 204 205 interface RunnableWithException { 206 void run() throws Exception; 207 } 208 209 static void uoe(RunnableWithException r) throws Exception { 210 checkException(r, UnsupportedOperationException.class); 211 } 212 213 static void nsae(RunnableWithException r) throws Exception { 214 checkException(r, NoSuchAlgorithmException.class); 215 } 216 217 static void npe(RunnableWithException r) throws Exception { 218 checkException(r, NullPointerException.class); 219 } 220 221 static void iae(RunnableWithException r) throws Exception { 222 checkException(r, IllegalArgumentException.class); 223 } 224 225 static void checkException(RunnableWithException r, Class ex) 226 throws Exception { 227 try { 228 r.run(); 229 } catch (Exception e) { 230 if (ex.isAssignableFrom(e.getClass())) { 231 return; 232 } 233 throw e; 234 } 235 throw new Exception("No exception thrown"); 236 } 237 238 static void assertTrue(boolean x) throws Exception { 239 if (!x) throw new Exception("Not true"); 240 } 241 242 static class MyContentSigner extends ContentSigner { 243 @Override 244 public byte[] generateSignedData( 245 ContentSignerParameters parameters, 246 boolean omitContent, 247 boolean applyTimestamp) throws NoSuchAlgorithmException, 248 CertificateException, IOException { 249 return new byte[0]; 250 } 251 } 252 }