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 19 package org.apache.harmony.security.tests.provider.crypto.serialization; 20 21 22 import org.apache.harmony.testframework.serialization.SerializationTest; 23 import org.apache.harmony.testframework.serialization.SerializationTest.SerializableAssert; 24 25 import junit.framework.Test; 26 import junit.framework.TestCase; 27 import junit.framework.TestSuite; 28 29 30 import java.security.Security; 31 import java.security.SecureRandom; 32 import java.security.NoSuchAlgorithmException; 33 import java.security.NoSuchProviderException; 34 35 import java.io.ByteArrayInputStream; 36 import java.io.ByteArrayOutputStream; 37 import java.io.FileInputStream; 38 import java.io.Serializable; 39 40 41 /** 42 * Tests against SecureRandom with SHA1PRNG serialization 43 */ 44 45 46 public class SHA1PRNG_SecureRandomTest extends TestCase { 47 48 49 private static final int LIMIT1 = 100; // constant value limiting loop 50 private static final int LIMIT2 = 50; // 51 52 private static final int CASES = 4; 53 54 static String algorithm = "SHA1PRNG"; // name of algorithm 55 static String provider = "Crypto"; // name of provider 56 57 private int testcase = 0; 58 59 private byte zero[] = new byte[0]; 60 61 private int flag; 62 private static final int SELF = 0; 63 private static final int GOLDEN = 1; 64 65 66 /** 67 * @return array of SecureRandom objects to be deserialized in tests. 68 */ getData()69 protected Object[] getData() { 70 71 SecureRandom sr; 72 Object[] data = new Object[5]; 73 74 75 for ( int i = 0; i < data.length ; i++ ) { 76 try { 77 sr = SecureRandom.getInstance(algorithm, provider); 78 79 switch (i) { 80 81 case 0 : break; 82 83 case 1 : sr.setSeed( zero ); 84 break; 85 86 case 2 : sr.setSeed( new byte[] { (byte)1 } ); 87 break; 88 89 case 3 : sr.nextBytes( zero ); 90 break; 91 92 case 4 : sr.nextBytes( new byte[1] ); 93 break; 94 } 95 data[i] = sr; 96 97 } catch (NoSuchAlgorithmException e) { 98 throw new RuntimeException("ATTENTION: " + e); 99 } catch (NoSuchProviderException e) { 100 throw new RuntimeException("ATTENTION: " + e); 101 } 102 } 103 return data; 104 }; 105 106 107 /** 108 * Comparing sequencies of bytes 109 * returned by "nextBytes(..)" of referenced and tested objects 110 */ testingSame(SecureRandom ref, SecureRandom test)111 private void testingSame(SecureRandom ref, SecureRandom test) { 112 113 byte refBytes[] = null; 114 byte testBytes[] = null; 115 116 for ( int k = 0; k < LIMIT2; k++ ) { 117 118 for ( int i = 0; i < LIMIT1; i++ ) { 119 120 refBytes = new byte[i]; 121 testBytes = new byte[i]; 122 123 ref.nextBytes(refBytes); 124 test.nextBytes(testBytes); 125 126 for (int j = 0; j < refBytes.length; j++ ) { 127 assertTrue("NOT same: testcase =" + testcase + 128 " k=" +k + " i=" +i + " j=" +j + 129 " refBytes[j]=" + refBytes[j] + " testBytes[j]=" + testBytes[j], 130 refBytes[j] == testBytes[j] ); 131 } 132 } 133 ref.setSeed(refBytes); 134 test.setSeed(testBytes); 135 } 136 } 137 138 139 /** 140 * Comparing sequencies of bytes 141 * returned by "nextBytes(..)" of referenced and tested objects 142 */ testingNotSame(SecureRandom ref, SecureRandom test)143 private void testingNotSame(SecureRandom ref, SecureRandom test) { 144 145 byte refTotalBytes[] = new byte[(LIMIT1*LIMIT1)/2]; 146 byte testTotalBytes[] = new byte[(LIMIT1*LIMIT1)/2]; 147 148 for ( int k = 0; k < LIMIT2; k++ ) { 149 150 byte refBytes[] = null; 151 byte testBytes[] = null; 152 153 int n = 0; 154 155 for ( int i = 0; i < LIMIT1; i++ ) { 156 157 refBytes = new byte[i]; 158 testBytes = new byte[i]; 159 160 ref.nextBytes(refBytes); 161 test.nextBytes(testBytes); 162 163 System.arraycopy(refBytes, 0, refTotalBytes, n, refBytes.length); 164 System.arraycopy(testBytes, 0, testTotalBytes, n, testBytes.length); 165 166 n += i; 167 } 168 169 boolean b = true; 170 int j = 0; 171 for ( int n1 = 0 ; n1 <= n ; n1++) { 172 173 b &= refTotalBytes[n1] == testTotalBytes[n1]; 174 175 if ( j >= 20 || n1 == n ) { 176 assertFalse("the same sequencies :: testcase=" + testcase + 177 " k=" +k + "n1 =" + n1, b); 178 b = true; 179 j = 0; 180 } 181 j++; 182 } 183 184 ref.setSeed(refBytes); 185 test.setSeed(testBytes); 186 } 187 } 188 189 190 private SerializableAssert comparator = new SerializableAssert(){ 191 192 /** 193 * Tests that data objects can be serialized and deserialized without exceptions 194 * and the deserialization produces object of the same class. 195 */ 196 public void assertDeserialized(Serializable reference, Serializable test) { 197 198 SecureRandom ref = (SecureRandom) reference; 199 SecureRandom tst = (SecureRandom) test; 200 201 boolean b; 202 byte seed[] = new byte[]{ 0 }; 203 204 switch ( testcase ) { 205 206 // non-initialized object 207 208 case 0 : // testing setSeed(..) 209 ref.setSeed(zero); 210 tst.setSeed(zero); 211 testingSame(ref, tst); 212 break; 213 214 case 5 : // testing setSeed(..) 215 ref.setSeed(seed); 216 tst.setSeed(seed); 217 testingSame(ref, tst); 218 break; 219 220 case 10 : // testing nextBytes(..) 221 ref.nextBytes(zero); 222 tst.nextBytes(zero); 223 testingNotSame(ref, tst); 224 break; 225 226 case 15 : // testing nextBytes(..) 227 ref.nextBytes(seed); 228 tst.nextBytes(seed); 229 testingNotSame(ref, tst); 230 break; 231 232 // object initialized with setSeed(zero) 233 234 case 1 : // testing setSeed(..) 235 ref.setSeed(zero); 236 tst.setSeed(zero); 237 testingSame(ref, tst); 238 break; 239 240 case 6 : // testing setSeed(..) 241 ref.setSeed(seed); 242 tst.setSeed(seed); 243 testingSame(ref, tst); 244 break; 245 246 case 11 : // testing nextBytes(..) 247 ref.nextBytes(zero); 248 tst.nextBytes(zero); 249 testingSame(ref, tst); 250 break; 251 252 case 16 : // testing nextBytes(..) 253 ref.nextBytes(seed); 254 tst.nextBytes(seed); 255 testingSame(ref, tst); 256 break; 257 258 // object initialized with setSeed(seed) 259 260 case 2 : // testing setSeed(..) 261 ref.setSeed(zero); 262 tst.setSeed(zero); 263 testingSame(ref, tst); 264 break; 265 266 case 7 : // testing setSeed(..) 267 ref.setSeed(seed); 268 tst.setSeed(seed); 269 testingSame(ref, tst); 270 break; 271 272 case 12 : // testing nextBytes(..) 273 ref.nextBytes(zero); 274 tst.nextBytes(zero); 275 testingSame(ref, tst); 276 break; 277 278 case 17 : // testing nextBytes(..) 279 ref.nextBytes(seed); 280 tst.nextBytes(seed); 281 testingSame(ref, tst); 282 break; 283 284 // object initialized with nextBytes(zero) 285 286 case 3 : // testing setSeed(..) 287 ref.setSeed(zero); 288 tst.setSeed(zero); 289 if ( flag == SELF ) { 290 testingSame(ref, tst); 291 } else { 292 testingNotSame(ref, tst); 293 } 294 break; 295 296 case 8 : // testing setSeed(..) 297 ref.setSeed(seed); 298 tst.setSeed(seed); 299 if ( flag == SELF ) { 300 testingSame(ref, tst); 301 } else { 302 testingNotSame(ref, tst); 303 } 304 break; 305 306 case 13 : // testing nextBytes(..) 307 ref.nextBytes(zero); 308 tst.nextBytes(zero); 309 if ( flag == SELF ) { 310 testingSame(ref, tst); 311 } else { 312 testingNotSame(ref, tst); 313 } 314 break; 315 316 case 18 : // testing nextBytes(..) 317 ref.nextBytes(seed); 318 tst.nextBytes(seed); 319 if ( flag == SELF ) { 320 testingSame(ref, tst); 321 } else { 322 testingNotSame(ref, tst); 323 } 324 break; 325 326 // object initialized with nextBytes(seed) 327 328 case 4 : // testing setSeed(..) 329 ref.setSeed(zero); 330 tst.setSeed(zero); 331 if ( flag == SELF ) { 332 testingSame(ref, tst); 333 } else { 334 testingNotSame(ref, tst); 335 } 336 break; 337 338 case 9 : // testing setSeed(..) 339 ref.setSeed(seed); 340 tst.setSeed(seed); 341 if ( flag == SELF ) { 342 testingSame(ref, tst); 343 } else { 344 testingNotSame(ref, tst); 345 } 346 break; 347 348 case 14 : // testing nextBytes(..) 349 ref.nextBytes(zero); 350 tst.nextBytes(zero); 351 if ( flag == SELF ) { 352 testingSame(ref, tst); 353 } else { 354 testingNotSame(ref, tst); 355 } 356 break; 357 358 case 19 : // testing nextBytes(..) 359 ref.nextBytes(seed); 360 tst.nextBytes(seed); 361 if ( flag == SELF ) { 362 testingSame(ref, tst); 363 } else { 364 testingNotSame(ref, tst); 365 } 366 break; 367 368 default: fail("ATTENTION: default case is not expected to happen"); 369 } 370 testcase++; 371 } 372 }; 373 374 375 /** 376 * Testing deserialized object. 377 */ testSerializationSelf()378 public void testSerializationSelf() throws Exception { 379 380 Object[] data; 381 382 flag = SELF; 383 for ( int i = 0; i < CASES; i++ ) { 384 385 data = getData(); 386 SerializationTest.verifySelf(data, comparator); 387 } 388 } 389 390 391 /** 392 * Testing that SecureRandom with SHA1PRNG objects can be deserialized from golden files. 393 */ testSerializationCompartibility()394 public void testSerializationCompartibility() throws Exception { 395 396 Object[] data; 397 398 flag = GOLDEN; 399 for ( int i = 0; i < CASES; i++ ) { 400 401 data = getData(); 402 SerializationTest.verifyGolden(this, data, comparator); 403 } 404 } 405 406 suite()407 public static Test suite() { 408 return new TestSuite(SHA1PRNG_SecureRandomTest.class); 409 } 410 411 } 412