Home | History | Annotate | Download | only in security
      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