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 18 package org.apache.harmony.tests.javax.security; 19 20 import java.security.NoSuchAlgorithmException; 21 import java.security.NoSuchProviderException; 22 import java.security.SecureRandom; 23 24 import junit.framework.TestCase; 25 26 /** 27 * Tests against methods in SecureRandom class object using 28 * SHA1PRNG_SecureRandomImpl. 29 */ 30 public class OldSHA1PRNGSecureRandomTest extends TestCase { 31 32 private static final int LENGTH = 20; // constant defining loop limit 33 34 private static final int INCR = 2; // constant defining loop increment 35 36 private static final String algorithm = "SHA1PRNG"; // algorithm's name 37 38 private static SecureRandom sr; // fields used by tests 39 40 private static SecureRandom sr2; // 41 42 /* 43 * @see TestCase#setUp() 44 */ 45 protected void setUp() throws Exception { 46 super.setUp(); 47 sr = SecureRandom.getInstance(algorithm); 48 sr2 = SecureRandom.getInstance(algorithm); 49 } 50 51 /** 52 * test against the "void generateSeed(int)" method; it checks out that the 53 * method throws NegativeArraySizeException if argument <0 54 */ 55 public final void testGenerateSeedint01() { 56 try { 57 sr.generateSeed(-1); 58 fail("generateSeed(-1) :: No NegativeArraySizeException"); 59 } catch (NegativeArraySizeException e) { 60 } 61 } 62 63 /** 64 * test against the "void generateSeed(int)" method; it checks out that 65 * number of bits returned is equal to one requested; the check includes 66 * case for argument's value == 0; 67 */ 68 public final void testGenerateSeedint02() { 69 for (int i = 0; i < LENGTH; i++) { 70 byte[] myBytes = sr.generateSeed(i); 71 assertFalse("unexpected: myBytes.length != i :: i==" + i + " myBytes.length=" 72 + myBytes.length, myBytes.length != i); 73 } 74 } 75 76 /** 77 * test against the "void generateSeed(int)" method; it checks out the 78 * quality of entropy (# of different bytes in sequential calls is more or 79 * equal to 50%) 80 */ 81 public final void testGenerateSeedint03() { 82 byte[] myBytes1; 83 byte[] myBytes2; 84 85 for (int i = 0; i < LENGTH; i += INCR) { 86 int n = 0; 87 myBytes1 = sr.generateSeed(i); 88 myBytes2 = sr.generateSeed(i); 89 90 for (int j = 0; j < i; j++) { 91 if (myBytes1[j] == myBytes2[j]) { 92 n++; 93 } 94 } 95 assertFalse("unexpected: n*2 > i :: i=" + i + " n=" + n, n * 2 > i); 96 } 97 } 98 99 /** 100 * test against the "void nextBytes(byte[])" method; it checks out that the 101 * method throws NPE if argument supplied is null 102 */ 103 public final void testNextBytesbyteArray01() { 104 try { 105 sr.nextBytes(null); 106 fail("unexpected: nextBytes(null) :: No NullPointerException"); 107 } catch (NullPointerException e) { 108 } 109 } 110 111 /** 112 * test against the "void nextBytes(byte[])" method; it checks out that 113 * different SecureRandom objects being supplied with the same seed return 114 * the same sequencies of bytes as results of their "nextBytes(byte[])" 115 * methods 116 */ 117 public final void testNextBytesbyteArray02() { 118 byte[] myBytes; 119 byte[] myBytes1; 120 byte[] myBytes2; 121 122 // case1: sequencies are of the same length 123 for (int i = 1; i < LENGTH; i += INCR) { 124 myBytes = new byte[i]; 125 126 for (int j = 1; j < i; j++) { 127 myBytes[j] = (byte) (j & 0xFF); 128 } 129 sr.setSeed(myBytes); 130 sr2.setSeed(myBytes); 131 132 for (int k = 1; k < LENGTH; k += INCR) { 133 myBytes1 = new byte[k]; 134 myBytes2 = new byte[k]; 135 sr.nextBytes(myBytes1); 136 sr2.nextBytes(myBytes2); 137 138 for (int l = 0; l < k; l++) { 139 assertFalse("unexpected: myBytes1[l] != myBytes2[l] :: l==" + l + " k=" + k 140 + " i=" + i + " myBytes1[l]=" + myBytes1[l] + " myBytes2[l]=" 141 + myBytes2[l], myBytes1[l] != myBytes2[l]); 142 } 143 } 144 } 145 146 // case2: sequencies are of different lengths 147 for (int n = 1; n < LENGTH; n += INCR) { 148 int n1 = 10; 149 int n2 = 20; 150 int n3 = 100; 151 byte[][] bytes1 = new byte[10][n1]; 152 byte[][] bytes2 = new byte[5][n2]; 153 154 for (int k = 0; k < bytes1.length; k++) { 155 sr.nextBytes(bytes1[k]); 156 } 157 for (int k = 0; k < bytes2.length; k++) { 158 sr2.nextBytes(bytes2[k]); 159 } 160 161 for (int k = 0; k < n3; k++) { 162 int i1 = k / n1; 163 int i2 = k % n1; 164 int i3 = k / n2; 165 int i4 = k % n2; 166 assertTrue("non-equality: i1=" + i1 + " i2=" + i2 + " i3=" + i3 + " i4=" + i4, 167 bytes1[i1][i2] == bytes2[i3][i4]); 168 } 169 } 170 } 171 172 /** 173 * test against the "void nextBytes(byte[])" method; it checks out that 174 * different SecureRandom objects being supplied with seed by themselves 175 * return different sequencies of bytes as results of their 176 * "nextBytes(byte[])" methods 177 */ 178 public final void testNextBytesbyteArray03() throws NoSuchAlgorithmException, 179 NoSuchProviderException { 180 /* these are needed to test new SecureRandom objects in loop */ 181 SecureRandom sr1; 182 SecureRandom sr2; 183 184 byte[] myBytes1; 185 byte[] myBytes2; 186 187 for (int i = 1; i < LENGTH / 2; i += INCR) { 188 sr1 = SecureRandom.getInstance(algorithm); 189 sr2 = SecureRandom.getInstance(algorithm); 190 191 boolean flag = true; 192 193 myBytes1 = new byte[i]; 194 myBytes2 = new byte[i]; 195 196 sr1.nextBytes(myBytes1); 197 sr2.nextBytes(myBytes2); 198 for (int j = 0; j < i; j++) { 199 flag &= myBytes1[j] == myBytes2[j]; 200 } 201 202 // check again to avoid intermittent failures 203 sr1.nextBytes(myBytes1); 204 sr2.nextBytes(myBytes2); 205 for (int j = 0; j < i; j++) { 206 flag &= myBytes1[j] == myBytes2[j]; 207 } 208 209 if (flag) { 210 // probability of false failure is 1.5*10^-5 per run for i=1 or 211 // less for i > 1 212 fail("TESTING RANDOM NUMBER GENERATOR QUALITY: IGNORE THIS FAILURE IF INTERMITTENT :: i=" 213 + i); 214 } 215 } 216 } 217 218 /** 219 * test against the "void nextBytes(byte[])" method; it checks out behavior 220 * of SecureRandom object in cases of passing byte array of zero length to 221 * "nextBytes(byte[])" method. The test contains two testcases: - first 222 * testcase checks out that if for two newly created SecureRandom objects 223 * invocation of "nextBytes(new byte[0])" method are first ones then further 224 * calls to nextBytes(..) methods return different byte arrays, that is, 225 * first "nextBytes(new byte[0])" aslo randomizes internal state; - second 226 * testcase checks out that if for two newly created SecureRandom objects 227 * invocation of "setSeed(..)" methods are first ones then further calls to 228 * "nextBytes(new byte[0])" methods has no effect 229 */ 230 public final void testNextBytesbyteArray04() throws NoSuchAlgorithmException, 231 NoSuchProviderException { 232 /* 233 * these are needed to test new SecureRandom objects in loop 234 */ 235 SecureRandom sr1; 236 SecureRandom sr2; 237 238 byte[] myBytes; 239 byte[] myBytes1; 240 byte[] myBytes2; 241 242 // case 1: 243 for (int i = 1; i < LENGTH / 2; i += INCR) { 244 sr1 = SecureRandom.getInstance(algorithm); 245 sr2 = SecureRandom.getInstance(algorithm); 246 247 sr1.nextBytes(new byte[0]); 248 sr2.nextBytes(new byte[0]); 249 250 boolean flag = true; 251 252 myBytes1 = new byte[i]; 253 myBytes2 = new byte[i]; 254 255 sr1.nextBytes(myBytes1); 256 sr2.nextBytes(myBytes2); 257 for (int j = 0; j < i; j++) { 258 flag &= myBytes1[j] == myBytes2[j]; 259 } 260 261 // check again to avoid intermittent failures 262 sr1.nextBytes(myBytes1); 263 sr2.nextBytes(myBytes2); 264 for (int j = 0; j < i; j++) { 265 flag &= myBytes1[j] == myBytes2[j]; 266 } 267 268 if (flag) { 269 // probability of false failure is 1.5*10^-5 per run for i=1 or 270 // less for i > 1 271 fail("TESTING RANDOM NUMBER GENERATOR QUALITY: IGNORE THIS FAILURE IF INTERMITTENT :: i=" 272 + i); 273 } 274 } 275 276 myBytes = new byte[] { 277 (byte) 0 278 }; 279 280 // case2: 281 for (int n = 1; n < LENGTH; n += INCR) { 282 byte[][] bytes1 = new byte[2][n]; 283 byte[][] bytes2 = new byte[2][n]; 284 285 sr1 = SecureRandom.getInstance(algorithm); 286 sr2 = SecureRandom.getInstance(algorithm); 287 288 sr1.setSeed(myBytes); 289 sr2.setSeed(myBytes); 290 291 sr1.nextBytes(bytes1[0]); 292 sr1.nextBytes(bytes1[1]); 293 294 sr2.nextBytes(bytes2[0]); 295 sr2.nextBytes(new byte[0]); 296 sr2.nextBytes(bytes2[1]); 297 298 for (int k = 0; k < 2; k++) { 299 for (int j = 0; j < n; j++) { 300 assertTrue("non-equality: k=" + k + " j=" + j + " bytes1[k][j]=" + bytes1[k][j] 301 + " bytes2[k][j]=" + bytes2[k][j], bytes1[k][j] == bytes2[k][j]); 302 } 303 } 304 } 305 } 306 307 /** 308 * test against the "void setSeed(byte[])" method; it checks out that the 309 * method throws NPE if argument supplied is null 310 */ 311 public final void testSetSeedbyteArray01() { 312 try { 313 sr.setSeed(null); 314 fail("setSeed(null) :: No NullPointerException"); 315 } catch (NullPointerException e) { 316 } 317 } 318 319 /** 320 * test against the "void setSeed(byte[])" method; it checks out that 321 * "setSeed(byte[])" method supplements its argument to current seed rather 322 * than replaces current seed 323 */ 324 public final void testSetSeedbyteArray02() throws NoSuchFieldException, SecurityException, 325 IllegalAccessException { 326 byte[] seed = new byte[LENGTH]; 327 byte[] bytes1 = new byte[LENGTH]; 328 byte[] bytes2 = new byte[LENGTH]; 329 boolean b; 330 331 for (int i = 0; i < seed.length; i++) { 332 seed[i] = (byte) i; 333 } 334 335 sr.setSeed(seed); 336 sr.setSeed(seed); 337 sr2.setSeed(seed); 338 339 sr.nextBytes(bytes1); 340 sr2.nextBytes(bytes2); 341 342 b = true; 343 for (int j = 0; j < bytes1.length; j++) { 344 b &= bytes1[j] == bytes2[j]; 345 } 346 assertFalse("unexpected: sequences are equal", b); 347 } 348 349 /** 350 * test against the "void setSeed(byte[])" method; it checks out that the 351 * "byte[0]" argument has no effect; there are two testcases: - if one of 352 * two SecureRandom objects supplied with the same seed is additionally 353 * supplied with such array, "nextBytes(..)" of both objects return the same 354 * bytes; - two byte arrays returned by "nextBytes(..)" in following 355 * sequence nextBytes(..); setSeed(new byte[0]); nextBytes(..); don't 356 * contain the same byte sequencies. 357 */ 358 public final void testSetSeedbyteArray03() throws NoSuchFieldException, SecurityException, 359 IllegalAccessException { 360 byte[] seed = new byte[LENGTH]; 361 byte[] bytes1; 362 byte[] bytes2; 363 364 for (int i = 0; i < seed.length; i++) { 365 seed[i] = (byte) i; 366 } 367 368 // testcase begins with "bytes1" and "bytes2" of zero length 369 for (int i = 0; i < LENGTH; i++) { 370 bytes1 = new byte[i]; 371 bytes2 = new byte[i]; 372 373 sr.setSeed(seed); 374 sr.setSeed(new byte[0]); 375 sr.nextBytes(bytes1); 376 377 sr2.setSeed(seed); 378 sr2.nextBytes(bytes2); 379 380 for (int j = 0; j < bytes1.length; j++) { 381 assertEquals("bytes1[j] != bytes2[j] :: j=" + j, bytes1[j], bytes2[j]); 382 } 383 } 384 385 for (int i = 1; i < LENGTH; i++) { 386 bytes1 = new byte[i]; 387 bytes2 = new byte[i]; 388 389 sr.setSeed(seed); 390 sr.nextBytes(bytes1); 391 sr.setSeed(new byte[0]); 392 sr.nextBytes(bytes2); 393 394 boolean b = true; 395 for (int j = 0; j < bytes1.length; j++) { 396 b &= bytes1[j] == bytes2[j]; 397 } 398 assertFalse("sequences are equal i=" + i, b); 399 } 400 } 401 } 402