Index: modules/security/src/test/impl/java/org/apache/harmony/security/tests/provider/crypto/CryptoProviderTest.java =================================================================== --- modules/security/src/test/impl/java/org/apache/harmony/security/tests/provider/crypto/CryptoProviderTest.java (revision 0) +++ modules/security/src/test/impl/java/org/apache/harmony/security/tests/provider/crypto/CryptoProviderTest.java (revision 0) @@ -0,0 +1,103 @@ +/* + * Licensed to the Apache Software Foundation (ASF) under one or more + * contributor license agreements. See the NOTICE file distributed with + * this work for additional information regarding copyright ownership. + * The ASF licenses this file to You under the Apache License, Version 2.0 + * (the "License"); you may not use this file except in compliance with + * the License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + + +package org.apache.harmony.security.tests.provider.crypto; + + +import org.apache.harmony.security.provider.crypto.CryptoProvider; + +import java.security.Security; +import java.security.SecureRandom; +import java.security.MessageDigest; +import java.security.Signature; +import java.security.KeyFactory; +import java.security.DigestException; +import java.security.NoSuchAlgorithmException; +import java.security.NoSuchProviderException; +import java.security.Provider; + +import junit.framework.Test; +import junit.framework.TestCase; +import junit.framework.TestSuite; + + +/** + * Tests against CryptoProvider. + */ + + +public class CryptoProviderTest extends TestCase { + + + private static final String providerName = "Crypto"; // name of provider + private static final String shaprng = "SHA1PRNG"; // name of algorithm + private static final String sha_1 = "SHA-1"; // name of algorithm + private static final String sha_1_alias = "SHA1"; // alias name + private static final String sha_1_alias2 = "SHA"; // alias name + + private static final String dsaNames[] = { "SHA1withDSA", + "SHAwithDSA", + "DSAwithSHA1", + "SHA1/DSA", + "SHA/DSA", + "SHA-1/DSA", + "DSA", + "DSS", + "OID.1.2.840.10040.4.3", + "1.2.840.10040.4.3", + "1.3.14.3.2.13", + "1.3.14.3.2.27" }; + + private static final String keyFactoryNames[] = { "DSA", + "1.3.14.3.2.12", + "1.2.840.10040.4.1" }; + + /** + * Test against CryptoProvider() methods. + */ + public void testCrypto() throws NoSuchAlgorithmException, NoSuchProviderException { + SecureRandom sr; + MessageDigest md; + Signature sign; + KeyFactory keyFactory; + + sr = SecureRandom.getInstance(shaprng, providerName); + + md = MessageDigest.getInstance(sha_1, providerName); + md = MessageDigest.getInstance(sha_1_alias, providerName); + md = MessageDigest.getInstance(sha_1_alias2, providerName); + + for ( int i = 0; i < dsaNames.length; i++ ) { + sign = Signature.getInstance(dsaNames[i], providerName); + } + + for ( int i = 0; i < keyFactoryNames.length; i++ ) { + keyFactory = KeyFactory.getInstance(keyFactoryNames[i], providerName); + } + } + + + public static Test suite() { + return new TestSuite(CryptoProviderTest.class); + } + + public static void main(String[] args) { + junit.textui.TestRunner.run(suite()); + } + + } Index: modules/security/src/test/impl/java/org/apache/harmony/security/tests/provider/crypto/SHA1ImplTest.java =================================================================== --- modules/security/src/test/impl/java/org/apache/harmony/security/tests/provider/crypto/SHA1ImplTest.java (revision 0) +++ modules/security/src/test/impl/java/org/apache/harmony/security/tests/provider/crypto/SHA1ImplTest.java (revision 0) @@ -0,0 +1,253 @@ +/* + * Licensed to the Apache Software Foundation (ASF) under one or more + * contributor license agreements. See the NOTICE file distributed with + * this work for additional information regarding copyright ownership. + * The ASF licenses this file to You under the Apache License, Version 2.0 + * (the "License"); you may not use this file except in compliance with + * the License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + + +package org.apache.harmony.security.tests.provider.crypto; + + +import junit.framework.Test; +import junit.framework.TestCase; +import junit.framework.TestSuite; + +import org.apache.harmony.security.provider.crypto.SHA1Impl; + +import java.security.MessageDigest; + + +/** + * Tests against methods in SHA1Impl class. + * The input data and results of computing are defined in Secure Hash Standard, + * see http://www.itl.nist.gov/fipspubs/fip180-1.htm + */ + + +public class SHA1ImplTest extends TestCase { + + + // SHA1Data constant used in below methods + private static final int INDEX = SHA1Impl.BYTES_OFFSET; + + private static MessageDigest md; + + + /* + * @see TestCase#setUp() + */ + protected void setUp() throws Exception { + super.setUp(); + md = MessageDigest.getInstance("SHA-1", "Crypto"); + } + + + /* + * The test checks out that for given three byte input + * a value returned by SHA1Impl is equal to both : + * - one defined in the Standard and + * - one calculated with alternative computation algorithm defined in the Standard. + */ + public final void testOneBlockMessage() { + + int[] words = new int[INDEX +6]; // working array to compute hash + + // values defined in examples in Secure Hash Standard + int[] hash1 = {0x67452301, 0xEFCDAB89, 0x98BADCFE, 0x10325476, 0xC3D2E1F0 }; + int[] hash = {0xA9993E36, 0x4706816A, 0xBA3E2571, 0x7850C26C, 0x9CD0D89D }; + + for (int i = 0; i < words.length; i++ ) { + words[i] = 0; + } + words[0] = 0x61626380; // constants from Secure Hash Standard + words[15] = 0x00000018; + + alternateHash(words, hash1); + + + md.update(new byte[]{0x61,0x62,0x63}); + byte[] dgst = md.digest(); + + for ( int k = 0; k < 5; k++ ) { + int i = k*4; + + int j = ((dgst[i ]&0xff)<<24) | ((dgst[i+1]&0xff)<<16) | + ((dgst[i+2]&0xff)<<8 ) | (dgst[i+3]&0xff) ; + + assertTrue("false1: k=" + k + " hash1[k]=" + Integer.toHexString(hash1[k]), + hash[k] == hash1[k] ); + + assertTrue("false2: k=" + k + " j=" + Integer.toHexString(j), hash[k] == j ); + } + } + + + + + /* + * The test checks out that SHA1Impl computes correct value + * if data supplied takes exactly fourteen words of sexteen word buffer. + */ + public final void testMultiBlockMessage() { + + // values defined in examples in Secure Hash Standard + int[] hash = {0x84983e44, 0x1c3bd26e, 0xbaae4aa1, 0xf95129e5, 0xe54670f1 }; + + // string defined in examples in Secure Hash Standard + md.update("abcdbcdecdefdefgefghfghighijhijkijkljklmklmnlmnomnopnopq".getBytes()); + byte[] dgst = md.digest(); + + for ( int k = 0; k < 5; k++ ) { + int i = k*4; + + int j = ((dgst[i ]&0xff)<<24) | ((dgst[i+1]&0xff)<<16) | + ((dgst[i+2]&0xff)<<8 ) | (dgst[i+3]&0xff) ; + + assertTrue("false: k=" + k + " j=" + Integer.toHexString(j), hash[k] == j ); + } + } + + + /* + * The test checks out that SHA1Impl returns correct values + * for four different cases of infilling internal buffer and computing intermediate hash. + */ + public final void testLongMessage() { + + // values defined in examples in Secure Hash Standard + int[] hash = {0x34aa973c, 0xd4c4daa4, 0xf61eeb2b, 0xdbad2731, 0x6534016f }; + + byte msgs[][] = new byte[][] { {0x61}, + {0x61, 0x61}, + {0x61, 0x61, 0x61}, + {0x61, 0x61, 0x61, 0x61} }; + + int lngs[] = new int[]{1000000, 500000, 333333, 250000}; + + for ( int n = 0; n < 4; n++ ) { + + for ( int i = 0; i < lngs[n]; i++) { + md.update(msgs[n]); + } + if ( n == 2 ) { + md.update(msgs[0]); + } + + byte[] dgst = md.digest(); + for ( int k = 0; k < 5; k++ ) { + int i = k*4; + + int j = ((dgst[i ]&0xff)<<24) | ((dgst[i+1]&0xff)<<16) | + ((dgst[i+2]&0xff)<<8 ) | (dgst[i+3]&0xff) ; + + assertTrue("false: n =" + n + " k=" + k + " j" + Integer.toHexString(j), + hash[k] == j ); + } + } + } + + + /** + * implements alternative algorithm described in the SECURE HASH STANDARD + */ + private void alternateHash(int[] bufW, int[] hash) { + + // constants defned in Secure Hash Standard + final int[] K = { + + 0x5A827999, 0x5A827999, 0x5A827999, 0x5A827999, + 0x5A827999, 0x5A827999, 0x5A827999, 0x5A827999, + 0x5A827999, 0x5A827999, 0x5A827999, 0x5A827999, + 0x5A827999, 0x5A827999, 0x5A827999, 0x5A827999, + 0x5A827999, 0x5A827999, 0x5A827999, 0x5A827999, + + 0x6ED9EBA1, 0x6ED9EBA1, 0x6ED9EBA1, 0x6ED9EBA1, + 0x6ED9EBA1, 0x6ED9EBA1, 0x6ED9EBA1, 0x6ED9EBA1, + 0x6ED9EBA1, 0x6ED9EBA1, 0x6ED9EBA1, 0x6ED9EBA1, + 0x6ED9EBA1, 0x6ED9EBA1, 0x6ED9EBA1, 0x6ED9EBA1, + 0x6ED9EBA1, 0x6ED9EBA1, 0x6ED9EBA1, 0x6ED9EBA1, + + 0x8F1BBCDC, 0x8F1BBCDC, 0x8F1BBCDC, 0x8F1BBCDC, + 0x8F1BBCDC, 0x8F1BBCDC, 0x8F1BBCDC, 0x8F1BBCDC, + 0x8F1BBCDC, 0x8F1BBCDC, 0x8F1BBCDC, 0x8F1BBCDC, + 0x8F1BBCDC, 0x8F1BBCDC, 0x8F1BBCDC, 0x8F1BBCDC, + 0x8F1BBCDC, 0x8F1BBCDC, 0x8F1BBCDC, 0x8F1BBCDC, + + 0xCA62C1D6, 0xCA62C1D6, 0xCA62C1D6, 0xCA62C1D6, + 0xCA62C1D6, 0xCA62C1D6, 0xCA62C1D6, 0xCA62C1D6, + 0xCA62C1D6, 0xCA62C1D6, 0xCA62C1D6, 0xCA62C1D6, + 0xCA62C1D6, 0xCA62C1D6, 0xCA62C1D6, 0xCA62C1D6, + 0xCA62C1D6, 0xCA62C1D6, 0xCA62C1D6, 0xCA62C1D6 + }; + + int a = hash[0]; //0x67452301 ; + int b = hash[1]; //0xEFCDAB89 ; + int c = hash[2]; //0x98BADCFE ; + int d = hash[3]; //0x10325476 ; + int e = hash[4]; //0xC3D2E1F0 ; + + // implementation constant and variables + + final int MASK = 0x0000000F; + int temp; + int s; + int tmp; + + // computation defined in Secure Hash Standard + for ( int t = 0 ; t < 80 ; t++ ) { + + s = t & MASK; + + if ( t >= 16) { + + tmp = bufW[ (s+13)&MASK ] ^ bufW[(s+8)&MASK ] ^ bufW[ (s+2)&MASK ] ^ bufW[s]; + bufW[s] = ( tmp<<1 ) | ( tmp>>>31 ); + } + + temp = ( a << 5 ) | ( a >>> 27 ); + + if ( t < 20 ) { + temp += ( b & c ) | ( (~b) & d ) ; + } else if ( t < 40 ) { + temp += b ^ c ^ d ; + } else if ( t < 60 ) { + temp += ( b & c ) | ( b & d ) | ( c & d ) ; + } else { + temp += b ^ c ^ d ; + } + + temp += e + bufW[s] + K[t] ; + e = d; + d = c; + c = ( b<<30 ) | ( b>>>2 ) ; + b = a; + a = temp; + } + hash[0] += a; + hash[1] += b; + hash[2] += c; + hash[3] += d; + hash[4] += e; + } + + + public static Test suite() { + return new TestSuite(SHA1ImplTest.class); + } + + public static void main(String[] args) { + junit.textui.TestRunner.run(suite()); + } + + } Index: modules/security/src/test/impl/java/org/apache/harmony/security/tests/provider/crypto/SHA1PRNG_SecureRandomTest.java =================================================================== --- modules/security/src/test/impl/java/org/apache/harmony/security/tests/provider/crypto/SHA1PRNG_SecureRandomTest.java (revision 0) +++ modules/security/src/test/impl/java/org/apache/harmony/security/tests/provider/crypto/SHA1PRNG_SecureRandomTest.java (revision 0) @@ -0,0 +1,421 @@ +/* + * Licensed to the Apache Software Foundation (ASF) under one or more + * contributor license agreements. See the NOTICE file distributed with + * this work for additional information regarding copyright ownership. + * The ASF licenses this file to You under the Apache License, Version 2.0 + * (the "License"); you may not use this file except in compliance with + * the License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + + +package org.apache.harmony.security.tests.provider.crypto; + + +import java.security.InvalidParameterException; +import java.security.Security; +import java.security.SecureRandom; +import java.security.NoSuchAlgorithmException; +import java.security.NoSuchProviderException; + +import junit.framework.Test; +import junit.framework.TestCase; +import junit.framework.TestSuite; + + +/** + * Tests against methods in SecureRandom class object using SHA1PRNG_SecureRandomImpl. + */ + + +public class SHA1PRNG_SecureRandomTest extends TestCase { + + + private static final int LENGTH = 100; // constant defining loop limit + private static final int INCR = 10; // constant defining loop increment + + private static final String algorithm = "SHA1PRNG"; // algorithm's name + private static final String provider = "Crypto"; // provider's name + + private static SecureRandom sr; // fields used by tests + private static SecureRandom sr2; // + + /* + * @see TestCase#setUp() + */ + protected void setUp() throws Exception { + super.setUp(); + sr = SecureRandom.getInstance(algorithm, provider); + sr2 = SecureRandom.getInstance(algorithm, provider); + } + + + /** + * test against the "void generateSeed(int)" method; + * it checks out that the method throws NegativeArraySizeException if argument <0 + */ + public final void testGenerateSeedint01() { + try { + sr.generateSeed(-1); + fail("generateSeed(-1) :: No NegativeArraySizeException"); + } catch (NegativeArraySizeException e) { + } + } + + + /** + * test against the "void generateSeed(int)" method; + * it checks out that number of bits returned is equal to one requested; + * the check includes case for argument's value == 0; + */ + public final void testGenerateSeedint02() { + + for ( int i = 0; i < LENGTH; i++ ) { + + byte[] myBytes = sr.generateSeed(i); + assertFalse("unexpected: myBytes.length != i :: i==" + i + + " myBytes.length=" + myBytes.length, myBytes.length != i); + } + } + + + /** + * test against the "void generateSeed(int)" method; + * it checks out the quality of entropy + * (# of different bytes in sequential calls is more or equal to 50%) + */ + public final void testGenerateSeedint03() { + + byte[] myBytes1; + byte[] myBytes2; + + for ( int i = 0; i < LENGTH; i+=INCR ) { + int n = 0; + myBytes1 = sr.generateSeed(i); + myBytes2 = sr.generateSeed(i); + + for ( int j = 0; j < i; j++ ) { + if ( myBytes1[j] == myBytes2[j] ) { + n++; + } + } + assertFalse("unexpected: n*2 > i :: i=" + i + " n=" + n, n*2 > i ); + } + } + + + /** + * test against the "void nextBytes(byte[])" method; + * it checks out that the method throws NPE if argument supplied is null + */ + public final void testNextBytesbyteArray01() { + + try { + sr.nextBytes(null); + fail("unexpected: nextBytes(null) :: No NullPointerException"); + } catch (NullPointerException e) { + } + } + + + /** + * test against the "void nextBytes(byte[])" method; + * it checks out that different SecureRandom objects + * being supplied with the same seed return the same sequencies of bytes + * as results of their "nextBytes(byte[])" methods + */ + public final void testNextBytesbyteArray02() { + + byte[] myBytes; + byte[] myBytes1; + byte[] myBytes2; + + // case1: sequencies are of the same length + for ( int i = 1; i < LENGTH; i+=INCR ) { + + myBytes = new byte[i]; + + for ( int j = 1; j < i ; j++ ) { + myBytes[j] = (byte)(j&0xFF); + } + sr.setSeed(myBytes); + sr2.setSeed(myBytes); + + for ( int k = 1; k < LENGTH; k+=INCR ) { + + myBytes1 = new byte[k]; + myBytes2 = new byte[k]; + sr.nextBytes(myBytes1); + sr2.nextBytes(myBytes2); + + for ( int l = 0; l < k; l++ ) { + assertFalse("unexpected: myBytes1[l] != myBytes2[l] :: l==" + l + + " k=" + k + " i=" + i + " myBytes1[l]=" + myBytes1[l] + + " myBytes2[l]=" + myBytes2[l], myBytes1[l] != myBytes2[l] ); + } + } + } + + // case2: sequencies are of different lengths + for ( int n = 1; n < LENGTH; n+=INCR ) { + int n1 = 10; + int n2 = 20; + int n3 = 100; + byte[][] bytes1 = new byte[10][n1]; + byte[][] bytes2 = new byte[ 5][n2]; + + for ( int k = 0; k < bytes1.length; k++ ) { + sr.nextBytes(bytes1[k]); + } + for ( int k = 0; k < bytes2.length; k++) { + sr2.nextBytes(bytes2[k]); + } + + for ( int k = 0; k < n3 ; k++ ) { + int i1 = k /n1; + int i2 = k %n1; + int i3 = k /n2; + int i4 = k %n2; + assertTrue("non-equality: i1="+ i1 +" i2="+i2 +" i3="+i3 +" i4=" +i4, + bytes1[i1][i2] == bytes2[i3][i4]); + } + } + } + + + /** + * test against the "void nextBytes(byte[])" method; + * it checks out that different SecureRandom objects + * being supplied with seed by themselves return different sequencies of bytes + * as results of their "nextBytes(byte[])" methods + */ + public final void testNextBytesbyteArray03() throws NoSuchAlgorithmException, + NoSuchProviderException { + + SecureRandom sr1; // these are needed to test new SecureRandom objects in loop + SecureRandom sr2; // + + byte[] myBytes; + byte[] myBytes1; + byte[] myBytes2; + + for ( int i = 1; i < LENGTH/2; i+=INCR ) { + + sr1 = SecureRandom.getInstance(algorithm, provider); + sr2 = SecureRandom.getInstance(algorithm, provider); + + boolean flag = true; + + myBytes1 = new byte[i]; + myBytes2 = new byte[i]; + sr1.nextBytes(myBytes1); + sr2.nextBytes(myBytes2); + + for ( int j = 0; j < i; j++ ) { + flag &= myBytes1[j] == myBytes2[j]; + } + if ( flag ) { + fail("unexpected: myBytes1[] == myBytes2[] :: i=" + i); + } + } + } + + + /** + * test against the "void nextBytes(byte[])" method; + * it checks out behavior of SecureRandom object in cases of passing + * byte array of zero length to "nextBytes(byte[])" method. + * The test contains two testcases: + * - first testcase checks out that if for two newly created SecureRandom objects + * invokation of "nextBytes(new byte[0])" method are first ones + * then further calls to nextBytes(..) methods return different byte arrays, + * that is, first "nextBytes(new byte[0])" aslo randomizes internal state; + * - second testcase checks out that if for two newly created SecureRandom objects + * invokation of "setSeed(..)" methods are first ones + * then further calls to "nextBytes(new byte[0])" methods has no effect + */ + public final void testNextBytesbyteArray04() throws NoSuchAlgorithmException, + NoSuchProviderException { + + SecureRandom sr1; // these are needed to test new SecureRandom objects in loop + SecureRandom sr2; // + + byte[] myBytes; + byte[] myBytes1; + byte[] myBytes2; + + // case 1: + for ( int i = 1; i < LENGTH/2; i+=INCR ) { + + sr1 = SecureRandom.getInstance(algorithm, provider); + sr2 = SecureRandom.getInstance(algorithm, provider); + + sr1.nextBytes(new byte[0]); + sr2.nextBytes(new byte[0]); + + boolean flag = true; + + myBytes1 = new byte[i]; + myBytes2 = new byte[i]; + sr1.nextBytes(myBytes1); + sr2.nextBytes(myBytes2); + + for ( int j = 0; j < i; j++ ) { + flag &= myBytes1[j] == myBytes2[j]; + } + if ( flag ) { + fail("unexpected: myBytes1[] == myBytes2[] :: i=" + i); + } + } + + myBytes = new byte[] { (byte)0 }; + + // case2: + for ( int n = 1; n < LENGTH; n+=INCR ) { + + byte[][] bytes1 = new byte[2][n]; + byte[][] bytes2 = new byte[2][n]; + + sr1 = SecureRandom.getInstance(algorithm, provider); + sr2 = SecureRandom.getInstance(algorithm, provider); + + sr1.setSeed(myBytes); + sr2.setSeed(myBytes); + + sr1.nextBytes(bytes1[0]); + sr1.nextBytes(bytes1[1]); + + sr2.nextBytes(bytes2[0]); + sr2.nextBytes(new byte[0]); + sr2.nextBytes(bytes2[1]); + + for ( int k = 0; k < 2 ; k++ ) { + for ( int j = 0; j < n; j++ ) { + assertTrue("non-equality: k="+ k +" j="+j + + " bytes1[k][j]="+bytes1[k][j] +" bytes2[k][j]=" +bytes2[k][j], + bytes1[k][j] == bytes2[k][j] ); + } + } + } + } + + + /** + * test against the "void setSeed(byte[])" method; + * it checks out that the method throws NPE if argument supplied is null + */ + public final void testSetSeedbyteArray01() { + + try { + sr.setSeed(null); + fail("setSeed(null) :: No NullPointerException"); + } catch (NullPointerException e) { + } + } + + + /** + * test against the "void setSeed(byte[])" method; + * it checks out that "setSeed(byte[])" method supplements its argument to current seed + * rather than replaces current seed + */ + public final void testSetSeedbyteArray02() throws NoSuchFieldException, + SecurityException, + IllegalAccessException { + byte[] seed = new byte[LENGTH]; + byte[] bytes1 = new byte[LENGTH]; + byte[] bytes2 = new byte[LENGTH]; + boolean b; + + for (int i = 0; i < seed.length; i++) { + seed[i] = (byte)i; + } + + sr.setSeed(seed); + sr.setSeed(seed); + sr2.setSeed(seed); + + sr.nextBytes(bytes1); + sr2.nextBytes(bytes2); + + b = true; + for (int j = 0; j < bytes1.length; j++) { + b &= bytes1[j] == bytes2[j]; + } + assertFalse("unexpected: sequences are equal", b); + } + + + /** + * test against the "void setSeed(byte[])" method; + * it checks out that the "byte[0]" argument has no effect; there are two testcases: + * - if one of two SecureRandom objects sipplied with the same seed is additionally + * sipplied with such array, "nextBytes(..)" of both objects return the same bytes; + * - two byte arrays returned by "nextBytes(..)" in following sequence + * nextBytes(..); setSeed(new byte[0]); nextBytes(..); + * don't contain the same byte sequencies. + */ + public final void testSetSeedbyteArray03() throws NoSuchFieldException, + SecurityException, + IllegalAccessException { + byte[] seed = new byte[LENGTH]; + byte[] bytes1; + byte[] bytes2; + + for (int i = 0; i < seed.length; i++) { + seed[i] = (byte)i; + } + + + // testcase begins with "bytes1" and "bytes2" of zero length + for ( int i = 0; i < LENGTH; i++ ) { + bytes1 = new byte[i]; + bytes2 = new byte[i]; + + sr.setSeed(seed); + sr.setSeed(new byte[0]); + sr.nextBytes(bytes1); + + sr2.setSeed(seed); + sr2.nextBytes(bytes2); + + for (int j = 0; j < bytes1.length; j++) { + assertEquals("bytes1[j] != bytes2[j] :: j=" +j, bytes1[j], bytes2[j]); + } + } + + for ( int i = 1; i < LENGTH; i++ ) { + bytes1 = new byte[i]; + bytes2 = new byte[i]; + + sr.setSeed(seed); + sr.nextBytes(bytes1); + sr.setSeed(new byte[0]); + sr.nextBytes(bytes2); + + boolean b = true; + for (int j = 0; j < bytes1.length; j++) { + b &= bytes1[j] == bytes2[j] ; + } + assertFalse("sequences are equal i=" + i, b); + } + + } + + + public static Test suite() { + return new TestSuite(SHA1PRNG_SecureRandomTest.class); + } + + public static void main(String[] args) { + junit.textui.TestRunner.run(suite()); + } + +} Index: modules/security/src/test/impl/java/org/apache/harmony/security/tests/provider/crypto/serialization/SHA1PRNG_SecureRandomTest.java =================================================================== --- modules/security/src/test/impl/java/org/apache/harmony/security/tests/provider/crypto/serialization/SHA1PRNG_SecureRandomTest.java (revision 0) +++ modules/security/src/test/impl/java/org/apache/harmony/security/tests/provider/crypto/serialization/SHA1PRNG_SecureRandomTest.java (revision 0) @@ -0,0 +1,415 @@ +/* + * Licensed to the Apache Software Foundation (ASF) under one or more + * contributor license agreements. See the NOTICE file distributed with + * this work for additional information regarding copyright ownership. + * The ASF licenses this file to You under the Apache License, Version 2.0 + * (the "License"); you may not use this file except in compliance with + * the License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + + +package org.apache.harmony.security.tests.provider.crypto.serialization; + + +import org.apache.harmony.testframework.serialization.SerializationTest; +import org.apache.harmony.testframework.serialization.SerializationTest.SerializableAssert; + +import junit.framework.Test; +import junit.framework.TestCase; +import junit.framework.TestSuite; + + +import java.security.Security; +import java.security.SecureRandom; +import java.security.NoSuchAlgorithmException; +import java.security.NoSuchProviderException; + +import java.io.ByteArrayInputStream; +import java.io.ByteArrayOutputStream; +import java.io.FileInputStream; +import java.io.Serializable; + + +/** + * Tests against SecureRandom with SHA1PRNG serialization + */ + + +public class SHA1PRNG_SecureRandomTest extends TestCase { + + + private static final int LIMIT1 = 100; // constant value limiting loop + private static final int LIMIT2 = 50; // + + private static final int CASES = 4; + + static String algorithm = "SHA1PRNG"; // name of algorithm + static String provider = "Crypto"; // name of provider + + private int testcase = 0; + + private byte zero[] = new byte[0]; + + private int flag; + private static final int SELF = 0; + private static final int GOLDEN = 1; + + + /** + * @return array of SecureRandom objects to be deserialized in tests. + */ + protected Object[] getData() { + + SecureRandom sr; + Object[] data = new Object[5]; + + + for ( int i = 0; i < data.length ; i++ ) { + try { + sr = SecureRandom.getInstance(algorithm, provider); + + switch (i) { + + case 0 : break; + + case 1 : sr.setSeed( zero ); + break; + + case 2 : sr.setSeed( new byte[] { (byte)1 } ); + break; + + case 3 : sr.nextBytes( zero ); + break; + + case 4 : sr.nextBytes( new byte[1] ); + break; + } + data[i] = sr; + + } catch (NoSuchAlgorithmException e) { + throw new RuntimeException("ATTENTION: " + e); + } catch (NoSuchProviderException e) { + throw new RuntimeException("ATTENTION: " + e); + } + } + return data; + }; + + + /** + * Compareing sequencies of bytes + * returned by "nextBytes(..)" of referenced and tested objects + */ + private void testingSame(SecureRandom ref, SecureRandom test) { + + byte refBytes[] = null; + byte testBytes[] = null; + + for ( int k = 0; k < LIMIT2; k++ ) { + + for ( int i = 0; i < LIMIT1; i++ ) { + + refBytes = new byte[i]; + testBytes = new byte[i]; + + ref.nextBytes(refBytes); + test.nextBytes(testBytes); + + for (int j = 0; j < refBytes.length; j++ ) { + assertTrue("NOT same: testcase =" + testcase + + " k=" +k + " i=" +i + " j=" +j + + " refBytes[j]=" + refBytes[j] + " testBytes[j]=" + testBytes[j], + refBytes[j] == testBytes[j] ); + } + } + ref.setSeed(refBytes); + test.setSeed(testBytes); + } + } + + + /** + * Compareing sequencies of bytes + * returned by "nextBytes(..)" of referenced and tested objects + */ + private void testingNotSame(SecureRandom ref, SecureRandom test) { + + byte refTotalBytes[] = new byte[(LIMIT1*LIMIT1)/2]; + byte testTotalBytes[] = new byte[(LIMIT1*LIMIT1)/2]; + + for ( int k = 0; k < LIMIT2; k++ ) { + + byte refBytes[] = null; + byte testBytes[] = null; + + int n = 0; + + for ( int i = 0; i < LIMIT1; i++ ) { + + refBytes = new byte[i]; + testBytes = new byte[i]; + + ref.nextBytes(refBytes); + test.nextBytes(testBytes); + + System.arraycopy(refBytes, 0, refTotalBytes, n, refBytes.length); + System.arraycopy(testBytes, 0, testTotalBytes, n, testBytes.length); + + n += i; + } + + boolean b = true; + int j = 0; + for ( int n1 = 0 ; n1 <= n ; n1++) { + + b &= refTotalBytes[n1] == testTotalBytes[n1]; + + if ( j >= 20 || n1 == n ) { + assertFalse("the same sequencies :: testcase=" + testcase + + " k=" +k + "n1 =" + n1, b); + b = true; + j = 0; + } + j++; + } + + ref.setSeed(refBytes); + test.setSeed(testBytes); + } + } + + + private SerializableAssert comparator = new SerializableAssert(){ + + /** + * Tests that data objects can be serialized and deserialized without exceptions + * and the deserialization produces object of the same class. + */ + public void assertDeserialized(Serializable reference, Serializable test) { + + SecureRandom ref = (SecureRandom) reference; + SecureRandom tst = (SecureRandom) test; + + boolean b; + byte seed[] = new byte[]{ 0 }; + + switch ( testcase ) { + + // non-initialized object + + case 0 : // testing setSeed(..) + ref.setSeed(zero); + tst.setSeed(zero); + testingSame(ref, tst); + break; + + case 5 : // testing setSeed(..) + ref.setSeed(seed); + tst.setSeed(seed); + testingSame(ref, tst); + break; + + case 10 : // testing nextBytes(..) + ref.nextBytes(zero); + tst.nextBytes(zero); + testingNotSame(ref, tst); + break; + + case 15 : // testing nextBytes(..) + ref.nextBytes(seed); + tst.nextBytes(seed); + testingNotSame(ref, tst); + break; + + // object initialized with setSeed(zero) + + case 1 : // testing setSeed(..) + ref.setSeed(zero); + tst.setSeed(zero); + testingSame(ref, tst); + break; + + case 6 : // testing setSeed(..) + ref.setSeed(seed); + tst.setSeed(seed); + testingSame(ref, tst); + break; + + case 11 : // testing nextBytes(..) + ref.nextBytes(zero); + tst.nextBytes(zero); + testingSame(ref, tst); + break; + + case 16 : // testing nextBytes(..) + ref.nextBytes(seed); + tst.nextBytes(seed); + testingSame(ref, tst); + break; + + // object initialized with setSeed(seed) + + case 2 : // testing setSeed(..) + ref.setSeed(zero); + tst.setSeed(zero); + testingSame(ref, tst); + break; + + case 7 : // testing setSeed(..) + ref.setSeed(seed); + tst.setSeed(seed); + testingSame(ref, tst); + break; + + case 12 : // testing nextBytes(..) + ref.nextBytes(zero); + tst.nextBytes(zero); + testingSame(ref, tst); + break; + + case 17 : // testing nextBytes(..) + ref.nextBytes(seed); + tst.nextBytes(seed); + testingSame(ref, tst); + break; + + // object initialized with nextBytes(zero) + + case 3 : // testing setSeed(..) + ref.setSeed(zero); + tst.setSeed(zero); + if ( flag == SELF ) { + testingSame(ref, tst); + } else { + testingNotSame(ref, tst); + } + break; + + case 8 : // testing setSeed(..) + ref.setSeed(seed); + tst.setSeed(seed); + if ( flag == SELF ) { + testingSame(ref, tst); + } else { + testingNotSame(ref, tst); + } + break; + + case 13 : // testing nextBytes(..) + ref.nextBytes(zero); + tst.nextBytes(zero); + if ( flag == SELF ) { + testingSame(ref, tst); + } else { + testingNotSame(ref, tst); + } + break; + + case 18 : // testing nextBytes(..) + ref.nextBytes(seed); + tst.nextBytes(seed); + if ( flag == SELF ) { + testingSame(ref, tst); + } else { + testingNotSame(ref, tst); + } + break; + + // object initialized with nextBytes(seed) + + case 4 : // testing setSeed(..) + ref.setSeed(zero); + tst.setSeed(zero); + if ( flag == SELF ) { + testingSame(ref, tst); + } else { + testingNotSame(ref, tst); + } + break; + + case 9 : // testing setSeed(..) + ref.setSeed(seed); + tst.setSeed(seed); + if ( flag == SELF ) { + testingSame(ref, tst); + } else { + testingNotSame(ref, tst); + } + break; + + case 14 : // testing nextBytes(..) + ref.nextBytes(zero); + tst.nextBytes(zero); + if ( flag == SELF ) { + testingSame(ref, tst); + } else { + testingNotSame(ref, tst); + } + break; + + case 19 : // testing nextBytes(..) + ref.nextBytes(seed); + tst.nextBytes(seed); + if ( flag == SELF ) { + testingSame(ref, tst); + } else { + testingNotSame(ref, tst); + } + break; + + default: fail("ATTENTION: default case is not expected to happen"); + } + testcase++; + } + }; + + + /** + * Testing deserialized object. + */ + public void testSerializationSelf() throws Exception { + + Object[] data; + + flag = SELF; + for ( int i = 0; i < CASES; i++ ) { + + data = getData(); + SerializationTest.verifySelf(data, comparator); + } + } + + + /** + * Testing that SecureRandom with SHA1PRNG objects can be deserialized from golden files. + */ + public void testSerializationCompartibility() throws Exception { + + Object[] data; + + flag = GOLDEN; + for ( int i = 0; i < CASES; i++ ) { + + data = getData(); + SerializationTest.verifyGolden(this, data, comparator); + } + } + + + public static Test suite() { + return new TestSuite(SHA1PRNG_SecureRandomTest.class); + } + + public static void main(String[] args) { + junit.textui.TestRunner.run(suite()); + } + +}