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*/
21
22package org.apache.harmony.crypto.tests.javax.crypto.spec;
23
24import java.util.Arrays;
25
26import javax.crypto.spec.SecretKeySpec;
27
28import junit.framework.Test;
29import junit.framework.TestCase;
30import junit.framework.TestSuite;
31
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                    + "when offset and len specify an invalid chunk of key.");
112        } catch (IllegalArgumentException e) {
113        }
114
115        try {
116            new SecretKeySpec(key, -1, key.length, algorithm);
117            fail("An ArrayIndexOutOfBoundsException should be thrown "
118                    + "in the case of negative offset.");
119        } catch (IllegalArgumentException e) {
120            fail("Not expected IllegalArgumentException was thrown.");
121        } catch (ArrayIndexOutOfBoundsException e) {
122        }
123
124        // Regression test for HARMONY-6347
125        try {
126            new SecretKeySpec(key, -1, key.length+2, algorithm);
127            fail("An ArrayIndexOutOfBoundsException should be thrown "
128                    + "in the case of negative offset.");
129        } catch (IllegalArgumentException e) {
130            fail("Not expected IllegalArgumentException was thrown.");
131        } catch (ArrayIndexOutOfBoundsException e) {
132        }
133
134        try {
135            new SecretKeySpec(key, offset, len, null);
136            fail("An IllegalArgumentException should be thrown "
137                    + "in the case of null algorithm.");
138        } catch (IllegalArgumentException e) {
139        }
140
141        SecretKeySpec ks = new SecretKeySpec(key, algorithm);
142        key[offset] ++;
143        assertFalse("The change of key specified in the constructor "
144                    + "should not cause the change of internal array.",
145                    key[offset] == ks.getEncoded()[0]);
146
147        // Regression test for HARMONY-1077
148        try {
149            new SecretKeySpec(new byte[] { 2 }, 4, -100, "CCC");
150            fail("ArrayIndexOutOfBoundsException expected");
151        } catch (ArrayIndexOutOfBoundsException e) {
152            //expected
153        }
154    }
155
156    /**
157     * getAlgorithm() method testing. Tests that returned value is
158     * equal to the value specified in the constructor.
159     */
160    public void testGetAlgorithm() {
161        byte[] key = new byte[] {1, 2, 3, 4, 5};
162        String algorithm = "Algorithm";
163
164        SecretKeySpec ks = new SecretKeySpec(key, algorithm);
165        assertEquals("The returned value does not equal to the "
166                + "value specified in the constructor.",
167                algorithm, ks.getAlgorithm());
168    }
169
170    /**
171     * getFormat() method testing. Tests that returned value is "RAW".
172     */
173    public void testGetFormat() {
174        byte[] key = new byte[] {1, 2, 3, 4, 5};
175        String algorithm = "Algorithm";
176
177        SecretKeySpec ks = new SecretKeySpec(key, algorithm);
178        assertTrue("The returned value is not \"RAW\".",
179                ks.getFormat() == "RAW");
180    }
181
182    /**
183     * getEncoded() method testing. Tests that returned array is equal to the
184     * array specified in the constructor. Checks that modification
185     * of returned array does not affect the internal array.
186     */
187    public void testGetEncoded() {
188        byte[] key = new byte[] {1, 2, 3, 4, 5};
189        String algorithm = "Algorithm";
190
191        SecretKeySpec ks = new SecretKeySpec(key, algorithm);
192        byte[] result = ks.getEncoded();
193        if (! Arrays.equals(key, result)) {
194            fail("The returned key does not equal to the specified "
195                    + "in the constructor.");
196        }
197        result[0] ++;
198        assertFalse("The change of returned by getEncoded() method key "
199                    + "should not cause the change of internal array.",
200                    result[0] == ks.getEncoded()[0]);
201
202		// Regression for HARMONY-78
203		int offset = 1;
204		int len = 4;
205		SecretKeySpec sks = new SecretKeySpec(key, offset, len, algorithm);
206		assertEquals("Key length is incorrect", len, sks.getEncoded().length);
207    }
208
209    /**
210     * hashCode() method testing. Tests that for equal objects hash codes
211     * are equal.
212     */
213    public void testHashCode() {
214        byte[] key = new byte[] {1, 2, 3, 4, 5};
215        String algorithm = "Algorithm";
216
217        SecretKeySpec ks1 = new SecretKeySpec(key, algorithm);
218        SecretKeySpec ks2 = new SecretKeySpec(key, algorithm);
219        assertTrue("Equal objects should have the same hash codes.",
220                                            ks1.hashCode() == ks2.hashCode());
221    }
222
223    /**
224     * equals(Object obj) method testing. Tests the correctness of equal
225     * operation: it should be reflexive, symmetric, transitive, consistent
226     * and should be false on null object.
227     */
228    public void testEquals() {
229        byte[] key = new byte[] {1, 2, 3, 4, 5};
230        String algorithm = "Algorithm";
231
232        SecretKeySpec ks1 = new SecretKeySpec(key, algorithm);
233        SecretKeySpec ks2 = new SecretKeySpec(key, algorithm);
234        SecretKeySpec ks3 = new SecretKeySpec(key, algorithm);
235
236        // checking for reflexive law:
237        assertTrue("The equivalence relation should be reflexive.",
238                                                        ks1.equals(ks1));
239
240        assertTrue("Objects built on the same parameters should be equal.",
241                                                        ks1.equals(ks2));
242        // checking for symmetric law:
243        assertTrue("The equivalence relation should be symmetric.",
244                                                        ks2.equals(ks1));
245
246        assertTrue("Objects built on the equal parameters should be equal.",
247                                                        ks2.equals(ks3));
248        // checking for transitive law:
249        assertTrue("The equivalence relation should be transitive.",
250                                                        ks1.equals(ks3));
251
252        assertFalse("Should not be equal to null object.",
253                                                        ks1.equals(null));
254
255        ks2 = new SecretKeySpec(new byte[] {1}, algorithm);
256        assertFalse("Objects should not be equal.", ks1.equals(ks2));
257
258        ks2 = new SecretKeySpec(key, "Another Algorithm");
259        assertFalse("Objects should not be equal.", ks1.equals(ks2));
260    }
261
262    public static Test suite() {
263        return new TestSuite(SecretKeySpecTest.class);
264    }
265
266}
267