1/* 2 * Copyright (c) 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/* @test 25 * @bug 8051408 8157308 8130181 26 * @modules java.base/sun.security.provider 27 * @build java.base/sun.security.provider.S 28 * @run main SpecTest 29 * @summary check the AbstractDrbg API etc 30 */ 31 32import java.security.*; 33import sun.security.provider.S; 34import static java.security.DrbgParameters.Capability.*; 35 36/** 37 * This test makes sure the AbstractDrbg API works as specified. It also 38 * checks the SecureRandom API. 39 * 40 * The implementations must be patched into java.base/sun.security.provider 41 * because AbstractDrbg is not a public interface. 42 */ 43public class SpecTest { 44 45 public static void main(String args[]) throws Exception { 46 47 // getInstance from a provider. 48 49 Provider p = new All("A", "0", ""); 50 byte[] bytes = new byte[100]; 51 52 // A non-DRBG 53 iae(() -> SecureRandom.getInstance("S1", null, p)); 54 nsae(() -> SecureRandom.getInstance("S1", 55 new SecureRandomParameters() {}, p)); 56 57 SecureRandom s1 = SecureRandom.getInstance("S1", p); 58 if (s1.getParameters() != null) { 59 throw new Exception(); 60 } 61 62 iae(() -> s1.nextBytes(bytes, null)); 63 uoe(() -> s1.nextBytes(bytes, new SecureRandomParameters() {})); 64 uoe(() -> s1.reseed()); 65 iae(() -> s1.reseed(null)); 66 uoe(() -> s1.reseed(new SecureRandomParameters() {})); 67 68 // A weak DRBG 69 iae(() -> SecureRandom.getInstance("S2", null, p)); 70 nsae(() -> SecureRandom.getInstance("S2", 71 new SecureRandomParameters() {}, p)); 72 nsae(() -> SecureRandom.getInstance("S2", 73 DrbgParameters.instantiation(256, NONE, null), p)); 74 nsae(() -> SecureRandom.getInstance("S2", 75 DrbgParameters.instantiation(-1, PR_AND_RESEED, null), p)); 76 nsae(() -> SecureRandom.getInstance("S2", 77 DrbgParameters.instantiation(-1, RESEED_ONLY, null), p)); 78 79 SecureRandom s2 = SecureRandom.getInstance("S2", 80 DrbgParameters.instantiation(-1, NONE, null), p); 81 equals(s2, "S2,SQUEEZE,128,none"); 82 equals(s2.getParameters(), "128,none,null"); 83 84 npe(() -> s2.nextBytes(null)); 85 iae(() -> s2.nextBytes(bytes, null)); 86 iae(() -> s2.nextBytes(bytes, new SecureRandomParameters() {})); 87 uoe(() -> s2.reseed()); 88 iae(() -> s2.reseed(null)); 89 90 iae(() -> s2.nextBytes(bytes, 91 DrbgParameters.nextBytes(-1, false, new byte[101]))); 92 s2.nextBytes(new byte[101], 93 DrbgParameters.nextBytes(-1, false, new byte[100])); 94 s2.nextBytes(bytes, 95 DrbgParameters.nextBytes(-1, false, new byte[100])); 96 97 // A strong DRBG 98 iae(() -> SecureRandom.getInstance("S3", null, p)); 99 nsae(() -> SecureRandom.getInstance("S3", 100 new SecureRandomParameters() {}, p)); 101 SecureRandom.getInstance("S3", 102 DrbgParameters.instantiation(192, PR_AND_RESEED, null), p); 103 104 SecureRandom s3 = SecureRandom.getInstance("S3", p); 105 equals(s3, "S3,SQUEEZE,128,reseed_only"); 106 equals(s3.getParameters(), "128,reseed_only,null"); 107 108 iae(() -> s3.nextBytes(bytes, 109 DrbgParameters.nextBytes(192, false, null))); 110 iae(() -> s3.nextBytes(bytes, 111 DrbgParameters.nextBytes(112, true, null))); 112 iae(() -> s3.reseed(new SecureRandomParameters() {})); 113 114 SecureRandom s32 = SecureRandom.getInstance( 115 "S3", DrbgParameters.instantiation(192, PR_AND_RESEED, null), p); 116 equals(s32, "S3,SQUEEZE,192,pr_and_reseed"); 117 equals(s32.getParameters(), "192,pr_and_reseed,null"); 118 119 s32.nextBytes(bytes, DrbgParameters.nextBytes(192, false, null)); 120 s32.nextBytes(bytes, DrbgParameters.nextBytes(112, true, null)); 121 s32.reseed(); 122 s32.reseed(DrbgParameters.reseed(true, new byte[100])); 123 124 // getInstance from competitive providers. 125 126 Provider l = new Legacy("L", "0", ""); 127 Provider w = new Weak("W", "0", ""); 128 Provider s = new Strong("S", "0", ""); 129 130 Security.addProvider(l); 131 Security.addProvider(w); 132 Security.addProvider(s); 133 134 SecureRandom s4; 135 136 try { 137 s4 = SecureRandom.getInstance("S"); 138 if (s4.getProvider() != l) { 139 throw new Exception(); 140 } 141 142 nsae(() -> SecureRandom.getInstance( 143 "S", DrbgParameters.instantiation(256, NONE, null))); 144 145 s4 = SecureRandom.getInstance( 146 "S", DrbgParameters.instantiation(192, NONE, null)); 147 if (s4.getProvider() != s) { 148 throw new Exception(); 149 } 150 151 s4 = SecureRandom.getInstance( 152 "S", DrbgParameters.instantiation(128, PR_AND_RESEED, null)); 153 if (s4.getProvider() != s) { 154 throw new Exception(); 155 } 156 157 s4 = SecureRandom.getInstance( 158 "S", DrbgParameters.instantiation(128, RESEED_ONLY, null)); 159 if (s4.getProvider() != s) { 160 throw new Exception(); 161 } 162 163 s4 = SecureRandom.getInstance( 164 "S", DrbgParameters.instantiation(128, NONE, null)); 165 if (s4.getProvider() != w) { 166 throw new Exception(); 167 } 168 } finally { 169 Security.removeProvider("L"); 170 Security.removeProvider("W"); 171 Security.removeProvider("S"); 172 } 173 } 174 175 public static class All extends Provider { 176 protected All(String name, String version, String info) { 177 super(name, version, info); 178 put("SecureRandom.S1", S.S1.class.getName()); 179 put("SecureRandom.S2", S.S2.class.getName()); 180 put("SecureRandom.S3", S.S3.class.getName()); 181 } 182 } 183 184 // Providing S with no params support 185 public static class Legacy extends Provider { 186 protected Legacy(String name, String version, String info) { 187 super(name, version, info); 188 put("SecureRandom.S", S.S1.class.getName()); 189 } 190 } 191 192 public static class Weak extends Provider { 193 protected Weak(String name, String version, String info) { 194 super(name, version, info); 195 put("SecureRandom.S", S.S2.class.getName()); 196 } 197 } 198 199 public static class Strong extends Provider { 200 protected Strong(String name, String version, String info) { 201 super(name, version, info); 202 put("SecureRandom.S", S.S3.class.getName()); 203 } 204 } 205 206 static void nsae(RunnableWithException r) throws Exception { 207 checkException(r, NoSuchAlgorithmException.class); 208 } 209 210 static void iae(RunnableWithException r) throws Exception { 211 checkException(r, IllegalArgumentException.class); 212 } 213 214 static void uoe(RunnableWithException r) throws Exception { 215 checkException(r, UnsupportedOperationException.class); 216 } 217 218 static void npe(RunnableWithException r) throws Exception { 219 checkException(r, NullPointerException.class); 220 } 221 222 interface RunnableWithException { 223 void run() throws Exception; 224 } 225 226 static void checkException(RunnableWithException r, Class ex) 227 throws Exception { 228 try { 229 r.run(); 230 } catch (Exception e) { 231 if (ex.isAssignableFrom(e.getClass())) { 232 return; 233 } 234 throw e; 235 } 236 throw new Exception("No exception thrown"); 237 } 238 239 static void equals(Object o, String s) throws Exception { 240 if (!o.toString().equals(s)) { 241 throw new Exception(o.toString() + " is not " + s); 242 } 243 } 244} 245