1/* 2 * Licensed to the Apache Software Foundation (ASF) under one or more 3 * contributor license agreements. See the NOTICE file distributed with 4 * this work for additional information regarding copyright ownership. 5 * The ASF licenses this file to You under the Apache License, Version 2.0 6 * (the "License"); you may not use this file except in compliance with 7 * the License. You may obtain a copy of the License at 8 * 9 * http://www.apache.org/licenses/LICENSE-2.0 10 * 11 * Unless required by applicable law or agreed to in writing, software 12 * distributed under the License is distributed on an "AS IS" BASIS, 13 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 14 * See the License for the specific language governing permissions and 15 * limitations under the License. 16 */ 17 18package org.apache.harmony.security.tests.java.security; 19 20import java.security.NoSuchAlgorithmException; 21import java.security.NoSuchProviderException; 22import java.security.Provider; 23import java.security.SecureRandom; 24import java.security.SecureRandomSpi; 25import java.security.Security; 26import junit.framework.TestCase; 27 28public class SecureRandom2Test extends TestCase { 29 30 private static final byte[] SEED_BYTES = { (byte) 33, (byte) 15, (byte) -3, 31 (byte) 22, (byte) 77, (byte) -16, (byte) -33, (byte) 56 }; 32 33 private static final int SEED_SIZE = 539; 34 35 private static final long SEED_VALUE = 5335486759L; 36 37 public void testGetProvider() { 38 SecureRandom sr1 = new SecureRandom(); 39 assertNotNull(sr1.getProvider()); 40 41 SecureRandom sr2 = new SecureRandom(SEED_BYTES); 42 assertNotNull(sr2.getProvider()); 43 44 MyProvider p = new MyProvider(); 45 46 MySecureRandom sr3 = new MySecureRandom(new MySecureRandomSpi(), p); 47 assertEquals(p, sr3.getProvider()); 48 try { 49 SecureRandom random = SecureRandom.getInstance("SHA1PRNG"); 50 assertNotNull(random.getProvider()); 51 } catch (NoSuchAlgorithmException e) { 52 fail("Unexpected NoSuchAlgorithmException"); 53 } 54 } 55 56 /** 57 * java.security.SecureRandom#SecureRandom() 58 */ 59 public void test_Constructor() { 60 // Test for method java.security.SecureRandom() 61 try { 62 new SecureRandom(); 63 } catch (Exception e) { 64 fail("Constructor threw exception : " + e); 65 } 66 } 67 68 /** 69 * java.security.SecureRandom#SecureRandom(byte[]) 70 */ 71 public void test_Constructor$B() { 72 // Test for method java.security.SecureRandom(byte []) 73 try { 74 new SecureRandom(SEED_BYTES); 75 } catch (Exception e) { 76 fail("Constructor threw exception : " + e); 77 } 78 79 try { 80 new SecureRandom(null); 81 fail("NullPointerException was not thrown for NULL parameter"); 82 } catch (NullPointerException e) { 83 //expected 84 } 85 } 86 87 /** 88 * java.security.SecureRandom#SecureRandom(java.security.SecureRandomSpi, java.security.Provider) 89 */ 90 public void test_ConstructorLjava_security_SecureRandomSpi_java_security_Provider() { 91 try { 92 new MySecureRandom(null, null); 93 } catch (Exception e) { 94 fail("Constructor threw exception : " + e); 95 } 96 97 try { 98 MyProvider p = new MyProvider(); 99 MySecureRandom sr = new MySecureRandom(new MySecureRandomSpi(), p); 100 assertEquals("unknown", sr.getAlgorithm()); 101 assertEquals(p, sr.getProvider()); 102 103 sr = new MySecureRandom(new MySecureRandomSpi(), null); 104 sr = new MySecureRandom(null, p); 105 } catch (Exception e) { 106 fail("Constructor threw exception : " + e); 107 } 108 109 } 110 111 /** 112 * java.security.SecureRandom#generateSeed(int) 113 */ 114 public void test_generateSeedI() { 115 // Test for method byte [] java.security.SecureRandom.generateSeed(int) 116 byte[] seed = new SecureRandom().generateSeed(SEED_SIZE); 117 assertEquals("seed has incorrect size", SEED_SIZE, seed.length); 118 119 try { 120 new SecureRandom().generateSeed(-42); 121 fail("expected an exception"); 122 } catch (Exception e) { 123 // ok 124 } 125 126 } 127 /** 128 * java.security.SecureRandom#getInstance(java.lang.String) 129 */ 130 public void test_getInstanceLjava_lang_String() { 131 // Test for method java.security.SecureRandom 132 // java.security.SecureRandom.getInstance(java.lang.String) 133 try { 134 SecureRandom.getInstance("SHA1PRNG"); 135 } catch (NoSuchAlgorithmException e) { 136 fail("getInstance did not find a SHA1PRNG algorithm"); 137 } 138 139 try { 140 SecureRandom.getInstance("MD2"); 141 fail("NoSuchAlgorithmException should be thrown for MD2 algorithm"); 142 } catch (NoSuchAlgorithmException e) { 143 //expected 144 } 145 } 146 147 /** 148 * java.security.SecureRandom#getInstance(java.lang.String, java.lang.String) 149 */ 150 public void test_getInstanceLjava_lang_StringLjava_lang_String() { 151 // Test for method java.security.SecureRandom 152 // java.security.SecureRandom.getInstance(java.lang.String, 153 // java.lang.String) 154 try { 155 Provider[] providers = Security 156 .getProviders("SecureRandom.SHA1PRNG"); 157 if (providers != null) { 158 for (int i = 0; i < providers.length; i++) { 159 SecureRandom 160 .getInstance("SHA1PRNG", providers[i].getName()); 161 }// end for 162 } else { 163 fail("No providers support SHA1PRNG"); 164 } 165 } catch (NoSuchAlgorithmException e) { 166 fail("getInstance did not find a SHA1PRNG algorithm"); 167 } catch (NoSuchProviderException e) { 168 fail("getInstance did not find the provider for SHA1PRNG"); 169 } 170 } 171 172 /** 173 * java.security.SecureRandom#getSeed(int) 174 */ 175 public void test_getSeedI() { 176 // Test for method byte [] java.security.SecureRandom.getSeed(int) 177 byte[] seed = SecureRandom.getSeed(SEED_SIZE); 178 assertEquals("seed has incorrect size", SEED_SIZE, seed.length); 179 180 try { 181 new SecureRandom().getSeed(-42); 182 fail("expected an exception"); 183 } catch (Exception e) { 184 // ok 185 } 186 } 187 188 /** 189 * java.security.SecureRandom#nextBytes(byte[]) 190 */ 191 public void test_nextBytes$B() { 192 // Test for method void java.security.SecureRandom.nextBytes(byte []) 193 byte[] bytes = new byte[313]; 194 try { 195 new SecureRandom().nextBytes(bytes); 196 } catch (Exception e) { 197 fail("next bytes not ok : " + e); 198 } 199 200 try { 201 new SecureRandom().nextBytes(null); 202 fail("expected exception"); 203 } catch (Exception e) { 204 // ok 205 } 206 } 207 208 /** 209 * java.security.SecureRandom#setSeed(byte[]) 210 */ 211 public void test_setSeed$B() { 212 // Test for method void java.security.SecureRandom.setSeed(byte []) 213 try { 214 new SecureRandom().setSeed(SEED_BYTES); 215 } catch (Exception e) { 216 fail("seed generation with bytes failed : " + e); 217 } 218 219 try { 220 new SecureRandom().setSeed(null); 221 fail("expected exception"); 222 } catch (Exception e) { 223 // ok 224 } 225 } 226 227 /** 228 * java.security.SecureRandom#setSeed(long) 229 */ 230 public void test_setSeedJ() { 231 // Test for method void java.security.SecureRandom.setSeed(long) 232 try { 233 new SecureRandom().setSeed(SEED_VALUE); 234 } catch (Exception e) { 235 fail("seed generation with long failed : " + e); 236 } 237 238 try { 239 new SecureRandom().setSeed(-1); 240 } catch (Exception e) { 241 fail("unexpected exception: " + e); 242 } 243 } 244 245 /** 246 * java.security.SecureRandom#getAlgorithm() 247 */ 248 public void test_getAlgorithm() { 249 // Regression for HARMONY-750 250 251 SecureRandomSpi spi = new SecureRandomSpi() { 252 253 protected void engineSetSeed(byte[] arg) { 254 } 255 256 protected void engineNextBytes(byte[] arg) { 257 } 258 259 protected byte[] engineGenerateSeed(int arg) { 260 return null; 261 } 262 }; 263 264 SecureRandom sr = new SecureRandom(spi, null) { 265 }; 266 267 assertEquals("unknown", sr.getAlgorithm()); 268 269 270 } 271 272 // Regression Test for HARMONY-3552. 273 public void test_nextJ() throws Exception { 274 MySecureRandom mySecureRandom = new MySecureRandom( 275 new MySecureRandomSpi(), null); 276 int numBits = 29; 277 int random = mySecureRandom.getNext(numBits); 278 assertEquals(numBits, Integer.bitCount(random)); 279 280 numBits = 0; 281 random = mySecureRandom.getNext(numBits); 282 assertEquals(numBits, Integer.bitCount(random)); 283 284 numBits = 40; 285 random = mySecureRandom.getNext(numBits); 286 assertEquals(32, Integer.bitCount(random)); 287 288 numBits = -1; 289 random = mySecureRandom.getNext(numBits); 290 assertEquals(0, Integer.bitCount(random)); 291 292 293 } 294 295 /** 296 * Validate that calling {@link SecureRandom#setSeed} <b>after</b> generating 297 * a random number compliments, but doesn't replace, the existing seed. 298 */ 299 public void testSetSeedComplimentsAfterFirstRandomNumber() throws Exception { 300 byte[] seed1 = { 'a', 'b', 'c' }; 301 SecureRandom sr1 = SecureRandom.getInstance("SHA1PRNG"); 302 sr1.nextInt(); 303 sr1.setSeed(seed1); 304 305 // This long value has no special meaning 306 assertTrue(6180693691264871500l != sr1.nextLong()); 307 } 308 309 class MySecureRandom extends SecureRandom { 310 private static final long serialVersionUID = 1L; 311 312 public MySecureRandom(SecureRandomSpi secureRandomSpi, Provider provider) { 313 super(secureRandomSpi, provider); 314 } 315 316 public int getNext(int numBits) { 317 return super.next(numBits); 318 } 319 } 320 321 class MySecureRandomSpi extends SecureRandomSpi { 322 private static final long serialVersionUID = 1L; 323 324 @Override 325 protected byte[] engineGenerateSeed(int arg0) { 326 return null; 327 } 328 329 @Override 330 protected void engineNextBytes(byte[] bytes) { 331 for (int i = 0; i < bytes.length; i++) { 332 bytes[i] = (byte) 0xFF; 333 } 334 } 335 336 @Override 337 protected void engineSetSeed(byte[] arg0) { 338 return; 339 } 340 } 341 342 class MyProvider extends Provider { 343 344 MyProvider() { 345 super("MyProvider", 1.0, "Provider for testing"); 346 put("MessageDigest.SHA-1", "SomeClassName"); 347 put("MessageDigest.abc", "SomeClassName"); 348 put("Alg.Alias.MessageDigest.SHA1", "SHA-1"); 349 } 350 351 MyProvider(String name, double version, String info) { 352 super(name, version, info); 353 } 354 355 public void putService(Provider.Service s) { 356 super.putService(s); 357 } 358 359 public void removeService(Provider.Service s) { 360 super.removeService(s); 361 } 362 363 } 364} 365