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* @author Alexander Y. Kleymenov
20* @version $Revision$
21*/
22
23package org.apache.harmony.crypto.tests.javax.crypto.spec;
24
25import junit.framework.Test;
26import junit.framework.TestCase;
27import junit.framework.TestSuite;
28
29import java.util.Arrays;
30
31import javax.crypto.spec.SecretKeySpec;
32
33/**
34 */
35public class SecretKeySpecTest extends TestCase {
36
37    /**
38     * SecretKeySpec(byte[] key, String algorithm) method testing. Tests that
39     * IllegalArgumentException is thrown in the case of inappropriate
40     * constructor parameters and that input iv array is
41     * copied to protect against subsequent modification.
42     */
43    public void testSecretKeySpec1() {
44        byte[] key = new byte[] {1, 2, 3, 4, 5};
45        String algorithm = "Algorithm";
46
47        try {
48            new SecretKeySpec(new byte[] {}, algorithm);
49            fail("An IllegalArgumentException should be thrown "
50                    + "in the case of empty key.");
51        } catch (IllegalArgumentException e) {
52        }
53
54        try {
55            new SecretKeySpec(null, algorithm);
56            fail("An IllegalArgumentException should be thrown "
57                    + "in the case of null key.");
58        } catch (IllegalArgumentException e) {
59        }
60
61        try {
62            new SecretKeySpec(key, null);
63            fail("An IllegalArgumentException should be thrown "
64                    + "in the case of null algorithm.");
65        } catch (IllegalArgumentException e) {
66        }
67
68        SecretKeySpec ks = new SecretKeySpec(key, algorithm);
69        key[0] ++;
70        assertFalse("The change of key specified in the constructor "
71                    + "should not cause the change of internal array.",
72                    key[0] == ks.getEncoded()[0]);
73    }
74
75    /**
76     * SecretKeySpec(byte[] key, int offset, int len, String algorithm) method
77     * testing. Tests that IllegalArgumentException is thrown in
78     * the case of inappropriate constructor parameters and that input iv array
79     * is copied to protect against subsequent modification.
80     */
81    public void testSecretKeySpec2() {
82        byte[] key = new byte[] {1, 2, 3, 4, 5};
83        int offset = 1;
84        int len = 4;
85        String algorithm = "Algorithm";
86
87        try {
88            new SecretKeySpec(new byte[] {}, 0, 0, algorithm);
89            fail("An IllegalArgumentException should be thrown "
90                    + "in the case of empty key.");
91        } catch (IllegalArgumentException e) {
92        }
93
94        try {
95            new SecretKeySpec(null, 0, 0, algorithm);
96            fail("An IllegalArgumentException should be thrown "
97                    + "in the case of null key.");
98        } catch (IllegalArgumentException e) {
99        }
100
101        try {
102            new SecretKeySpec(key, offset, len, null);
103            fail("An IllegalArgumentException should be thrown "
104                    + "in the case of short key algorithm.");
105        } catch (IllegalArgumentException e) {
106        }
107
108        try {
109            new SecretKeySpec(key, offset, key.length, algorithm);
110            fail("An IllegalArgumentException should be thrown "
111                    + "in the case of null key.");
112        } catch (IllegalArgumentException e) {
113        }
114
115        try {
116            new SecretKeySpec(key, 0, -1, algorithm);
117            fail("An ArrayIndexOutOfBoundsException should be thrown "
118                    + "in the case of illegal length.");
119        } catch (IllegalArgumentException e) {
120            fail("Not expected IllegalArgumentException was thrown.");
121        } catch (ArrayIndexOutOfBoundsException e) {
122        }
123
124        SecretKeySpec ks = new SecretKeySpec(key, algorithm);
125        key[offset] ++;
126        assertFalse("The change of key specified in the constructor "
127                    + "should not cause the change of internal array.",
128                    key[offset] == ks.getEncoded()[0]);
129
130        // Regression test for HARMONY-1077
131        try {
132            new SecretKeySpec(new byte[] { 2 }, 4, -100, "CCC");
133            fail("ArrayIndexOutOfBoundsException expected");
134        } catch (ArrayIndexOutOfBoundsException e) {
135            //expected
136        }
137    }
138
139    public void testSecretKeySpec3() {
140        byte[] key = new byte[] {1, 2, 3, 4, 5};
141        int offset = 1;
142        int len = 4;
143        String algorithm = "Algorithm";
144
145        try {
146            new SecretKeySpec(key, -1, key.length, algorithm);
147            fail("An ArrayIndexOutOfBoundsException should be thrown "
148                    + "in the case of illegal offset.");
149        } catch (IllegalArgumentException e) {
150            fail("Not expected IllegalArgumentException was thrown.");
151        } catch (ArrayIndexOutOfBoundsException e) {
152        }
153    }
154
155    /**
156     * getAlgorithm() method testing. Tests that returned value is
157     * equal to the value specified in the constructor.
158     */
159    public void testGetAlgorithm() {
160        byte[] key = new byte[] {1, 2, 3, 4, 5};
161        String algorithm = "Algorithm";
162
163        SecretKeySpec ks = new SecretKeySpec(key, algorithm);
164        assertEquals("The returned value does not equal to the "
165                + "value specified in the constructor.",
166                algorithm, ks.getAlgorithm());
167    }
168
169    /**
170     * getFormat() method testing. Tests that returned value is "RAW".
171     */
172    public void testGetFormat() {
173        byte[] key = new byte[] {1, 2, 3, 4, 5};
174        String algorithm = "Algorithm";
175
176        SecretKeySpec ks = new SecretKeySpec(key, algorithm);
177        assertTrue("The returned value is not \"RAW\".",
178                ks.getFormat() == "RAW");
179    }
180
181    /**
182     * getEncoded() method testing. Tests that returned array is equal to the
183     * array specified in the constructor. Checks that modification
184     * of returned array does not affect the internal array.
185     */
186    public void testGetEncoded() {
187        byte[] key = new byte[] {1, 2, 3, 4, 5};
188        String algorithm = "Algorithm";
189
190        SecretKeySpec ks = new SecretKeySpec(key, algorithm);
191        byte[] result = ks.getEncoded();
192        if (! Arrays.equals(key, result)) {
193            fail("The returned key does not equal to the specified "
194                    + "in the constructor.");
195        }
196        result[0] ++;
197        assertFalse("The change of returned by getEncoded() method key "
198                    + "should not cause the change of internal array.",
199                    result[0] == ks.getEncoded()[0]);
200
201        // Regression for HARMONY-78
202        int offset = 1;
203        int len = 4;
204        SecretKeySpec sks = new SecretKeySpec(key, offset, len, algorithm);
205        assertEquals("Key length is incorrect", len, sks.getEncoded().length);
206    }
207
208    /**
209     * hashCode() method testing. Tests that for equal objects hash codes
210     * are equal.
211     */
212    public void testHashCode() {
213        byte[] key = new byte[] {1, 2, 3, 4, 5};
214        String algorithm = "Algorithm";
215
216        SecretKeySpec ks1 = new SecretKeySpec(key, algorithm);
217        SecretKeySpec ks2 = new SecretKeySpec(key, algorithm);
218        assertTrue("Equal objects should have the same hash codes.",
219                                            ks1.hashCode() == ks2.hashCode());
220    }
221
222    /**
223     * equals(Object obj) method testing. Tests the correctness of equal
224     * operation: it should be reflexive, symmetric, transitive, consistent
225     * and should be false on null object.
226     */
227    public void testEquals() {
228        byte[] key = new byte[] {1, 2, 3, 4, 5};
229        String algorithm = "Algorithm";
230
231        SecretKeySpec ks1 = new SecretKeySpec(key, algorithm);
232        SecretKeySpec ks2 = new SecretKeySpec(key, algorithm);
233        SecretKeySpec ks3 = new SecretKeySpec(key, algorithm);
234
235        // checking for reflexive law:
236        assertTrue("The equivalence relation should be reflexive.",
237                                                        ks1.equals(ks1));
238
239        assertTrue("Objects built on the same parameters should be equal.",
240                                                        ks1.equals(ks2));
241        // checking for symmetric law:
242        assertTrue("The equivalence relation should be symmetric.",
243                                                        ks2.equals(ks1));
244
245        assertTrue("Objects built on the equal parameters should be equal.",
246                                                        ks2.equals(ks3));
247        // checking for transitive law:
248        assertTrue("The equivalence relation should be transitive.",
249                                                        ks1.equals(ks3));
250
251        assertFalse("Should not be equal to null object.",
252                                                        ks1.equals(null));
253
254        ks2 = new SecretKeySpec(new byte[] {1}, algorithm);
255        assertFalse("Objects should not be equal.", ks1.equals(ks2));
256
257        ks2 = new SecretKeySpec(key, "Another Algorithm");
258        assertFalse("Objects should not be equal.", ks1.equals(ks2));
259    }
260
261    public static Test suite() {
262        return new TestSuite(SecretKeySpecTest.class);
263    }
264}
265
266