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* @author Alexander Y. Kleymenov
19*/
20
21package org.apache.harmony.crypto.tests.javax.crypto.spec;
22
23import java.lang.NullPointerException;
24import java.security.InvalidKeyException;
25import java.util.Arrays;
26
27import javax.crypto.spec.DESKeySpec;
28
29import junit.framework.Test;
30import junit.framework.TestCase;
31import junit.framework.TestSuite;
32
33/**
34 */
35
36public class DESKeySpecTest extends TestCase {
37
38    // DES weak and semi-weak keys
39    // Got from:
40    // FIP PUB 74
41    // FEDERAL INFORMATION PROCESSING STANDARDS PUBLICATION 1981
42    // GUIDELINES FOR IMPLEMENTING AND USING THE NBS DATA ENCRYPTION STANDARD
43    // http://www.dice.ucl.ac.be/crypto/standards/fips/fip74/fip74-1.pdf
44    private static final byte[][] semiweaks = {
45                {(byte) 0xE0, (byte) 0x01, (byte) 0xE0, (byte) 0x01,
46                 (byte) 0xF1, (byte) 0x01, (byte) 0xF1, (byte) 0x01},
47
48                {(byte) 0x01, (byte) 0xE0, (byte) 0x01, (byte) 0xE0,
49                 (byte) 0x01, (byte) 0xF1, (byte) 0x01, (byte) 0xF1},
50
51                {(byte) 0xFE, (byte) 0x1F, (byte) 0xFE, (byte) 0x1F,
52                 (byte) 0xFE, (byte) 0x0E, (byte) 0xFE, (byte) 0x0E},
53
54                {(byte) 0x1F, (byte) 0xFE, (byte) 0x1F, (byte) 0xFE,
55                 (byte) 0x0E, (byte) 0xFE, (byte) 0x0E, (byte) 0xFE},
56
57                {(byte) 0xE0, (byte) 0x1F, (byte) 0xE0, (byte) 0x1F,
58                 (byte) 0xF1, (byte) 0x0E, (byte) 0xF1, (byte) 0x0E},
59
60                {(byte) 0x1F, (byte) 0xE0, (byte) 0x1F, (byte) 0xE0,
61                 (byte) 0x0E, (byte) 0xF1, (byte) 0x0E, (byte) 0xF1},
62
63                {(byte) 0x01, (byte) 0xFE, (byte) 0x01, (byte) 0xFE,
64                 (byte) 0x01, (byte) 0xFE, (byte) 0x01, (byte) 0xFE},
65
66                {(byte) 0xFE, (byte) 0x01, (byte) 0xFE, (byte) 0x01,
67                 (byte) 0xFE, (byte) 0x01, (byte) 0xFE, (byte) 0x01},
68
69                {(byte) 0x01, (byte) 0x1F, (byte) 0x01, (byte) 0x1F,
70                 (byte) 0x01, (byte) 0x0E, (byte) 0x01, (byte) 0x0E},
71
72                {(byte) 0x1F, (byte) 0x01, (byte) 0x1F, (byte) 0x01,
73                 (byte) 0x0E, (byte) 0x01, (byte) 0x0E, (byte) 0x01},
74
75                {(byte) 0xE0, (byte) 0xFE, (byte) 0xE0, (byte) 0xFE,
76                 (byte) 0xF1, (byte) 0xFE, (byte) 0xF1, (byte) 0xFE},
77
78                {(byte) 0xFE, (byte) 0xE0, (byte) 0xFE, (byte) 0xE0,
79                 (byte) 0xFE, (byte) 0xF1, (byte) 0xFE, (byte) 0xF1},
80
81                {(byte) 0x01, (byte) 0x01, (byte) 0x01, (byte) 0x01,
82                 (byte) 0x01, (byte) 0x01, (byte) 0x01, (byte) 0x01},
83
84                {(byte) 0xFE, (byte) 0xFE, (byte) 0xFE, (byte) 0xFE,
85                 (byte) 0xFE, (byte) 0xFE, (byte) 0xFE, (byte) 0xFE},
86
87                {(byte) 0xE0, (byte) 0xE0, (byte) 0xE0, (byte) 0xE0,
88                 (byte) 0xF1, (byte) 0xF1, (byte) 0xF1, (byte) 0xF1},
89
90                {(byte) 0x1F, (byte) 0x1F, (byte) 0x1F, (byte) 0x1F,
91                 (byte) 0x0E, (byte) 0x0E, (byte) 0x0E, (byte) 0x0E},
92            };
93
94    /* DES not weak or semi-weak keys */
95    private static final byte[][] notsemiweaks = {
96                {(byte) 0x1f, (byte) 0x1f, (byte) 0x1f, (byte) 0x1f,
97                 (byte) 0x1f, (byte) 0x1f, (byte) 0x1f, (byte) 0x1f},
98
99                {(byte) 0xe0, (byte) 0xe0, (byte) 0xe0, (byte) 0xe0,
100                 (byte) 0xe0, (byte) 0xe0, (byte) 0xe0, (byte) 0xe0}
101            };
102    /**
103     * Constructors testing. Tests behavior of each of two constructors
104     * in the cases of: null array, short array, normal array.
105     */
106    public void testDESKeySpec() {
107        try {
108            new DESKeySpec((byte []) null);
109            fail("Should raise an NullPointerException "
110                    + "in case of null byte array.");
111        } catch (NullPointerException e) {
112        } catch (InvalidKeyException e) {
113            fail("Should raise an NullPointerException "
114                    + "in case of null byte array.");
115        }
116        try {
117            new DESKeySpec(new byte [] {1, 2, 3});
118            fail("Should raise an InvalidKeyException on a short byte array.");
119        } catch (NullPointerException e) {
120            fail("Unexpected NullPointerException was thrown.");
121        } catch (InvalidKeyException e) {
122        }
123        try {
124            new DESKeySpec(new byte[] {1, 2, 3, 4, 5, 6, 7, 8});
125        } catch (NullPointerException e) {
126            fail("Unexpected NullPointerException was thrown.");
127        } catch (InvalidKeyException e) {
128            fail("Unexpected InvalidKeyException was thrown.");
129        }
130        try {
131            new DESKeySpec((byte []) null, 1);
132            fail("Should raise an NullPointerException "
133                    + "in case of null byte array.");
134        } catch (NullPointerException e) {
135        } catch (InvalidKeyException e) {
136            fail("Should raise an NullPointerException "
137                    + "in case of null byte array.");
138        }
139        try {
140            new DESKeySpec(new byte []  {1, 2, 3, 4, 5, 6, 7, 8}, 1);
141            fail("Should raise an InvalidKeyException on a short byte array.");
142        } catch (NullPointerException e) {
143            fail("Unexpected NullPointerException was thrown.");
144        } catch (InvalidKeyException e) {
145        }
146        try {
147            new DESKeySpec(new byte[] {1, 2, 3, 4, 5, 6, 7, 8, 9}, 1);
148        } catch (NullPointerException e) {
149            fail("Unexpected NullPointerException was thrown.");
150        } catch (InvalidKeyException e) {
151            fail("Unexpected InvalidKeyException was thrown.");
152        }
153    }
154
155    /**
156     * getKey() method testing. Checks that modification of returned key
157     * does not affect the internal key. Also test check an equality of
158     * the key with the key specified in the constructor. The object under
159     * the test is created by different constructors.
160     */
161    public void testGetKey() {
162        byte[] key = {1, 2, 3, 4, 5, 6, 7, 8};
163        DESKeySpec ks;
164        try {
165            ks = new DESKeySpec(key);
166        } catch (InvalidKeyException e) {
167            fail("InvalidKeyException should not be thrown.");
168            return;
169        }
170        byte[] res = ks.getKey();
171        assertTrue("The returned array should be equal to the specified "
172                    + "in constructor.", Arrays.equals(key, res));
173        res[0] += 1;
174        assertFalse("The modification of returned key should not affect"
175                    + "the underlying key.", key[0] == res[0]);
176
177        byte[] key1 = {1, 2, 3, 4, 5, 6, 7, 8, 9, 0};
178        try {
179            ks = new DESKeySpec(key1, 2);
180        } catch (InvalidKeyException e) {
181            fail("InvalidKeyException should not be thrown.");
182            return;
183        }
184        res = ks.getKey();
185        assertNotSame("The returned array should not be the same object "
186                    + "as specified in a constructor.", key1, res);
187        byte[] exp = new byte[8];
188        System.arraycopy(key1, 2, exp, 0, 8);
189        assertTrue("The returned array should be equal to the specified "
190                    + "in constructor.", Arrays.equals(exp, res));
191    }
192
193    /**
194     * isParityAdjusted(byte[] key, offset) method testing. Tests if the
195     * method throws appropriate exceptions on incorrect byte array, if
196     * it returns false on the key which is not parity adjusted, and if
197     * it returns true on parity adjusted key.
198     */
199    public void testIsParityAdjusted() {
200        try {
201            DESKeySpec.isParityAdjusted(null, 1);
202            fail("Should raise an InvalidKeyException "
203                    + "in case of null byte array.");
204        } catch (NullPointerException e) {
205            fail("Unexpected NullPointerException was thrown.");
206        } catch (InvalidKeyException e) {
207        }
208
209        byte[] key = {1, 2, 3, 4, 5, 6, 7, 8};
210        try {
211            DESKeySpec.isParityAdjusted(key, 1);
212            fail("Should raise an InvalidKeyException "
213                    + "in case of short byte array.");
214        } catch (NullPointerException e) {
215            fail("Unexpected NullPointerException was thrown.");
216        } catch (InvalidKeyException e) {
217        }
218
219        byte[] key_not_pa = {1, 2, 3, 4, 5, 6, 7, 8};
220        try {
221            assertFalse("Method returns true when false is expected.",
222                        DESKeySpec.isParityAdjusted(key_not_pa, 0));
223        } catch (NullPointerException e) {
224            fail("Unexpected NullPointerException was thrown.");
225        } catch (InvalidKeyException e) {
226            fail("Unexpected InvalidKeyException was thrown.");
227        }
228
229        byte[] key_pa = {(byte) 128, (byte) 131, (byte) 133, (byte) 134,
230                         (byte) 137, (byte) 138, (byte) 140, (byte) 143};
231        try {
232            assertTrue("Method returns false when true is expected.",
233                        DESKeySpec.isParityAdjusted(key_pa, 0));
234        } catch (NullPointerException e) {
235            fail("Unexpected NullPointerException was thrown.");
236        } catch (InvalidKeyException e) {
237            fail("Unexpected InvalidKeyException was thrown.");
238        }
239    }
240
241    /**
242     * isWeak(byte[] key, int offset) method testing. Tests if the
243     * method throws appropriate exceptions on incorrect byte array, if
244     * it returns true on weak or semi-weak keys, and if it returns
245     * false on other keys.
246     */
247    public void testIsWeak() {
248        try {
249            DESKeySpec.isWeak(null, 1);
250            fail("Should raise an InvalidKeyException "
251                    + "in case of null byte array.");
252        } catch (NullPointerException e) {
253            fail("Unexpected NullPointerException was thrown.");
254        } catch (InvalidKeyException e) {
255        }
256
257        byte[] key = {1, 2, 3, 4, 5, 6, 7, 8};
258        try {
259            DESKeySpec.isWeak(key, 1);
260            fail("Should raise an InvalidKeyException "
261                    + "in case of short byte array.");
262        } catch (NullPointerException e) {
263            fail("Unexpected NullPointerException was thrown.");
264        } catch (InvalidKeyException e) {
265        }
266
267        for (int i=0; i<semiweaks.length; i++) {
268            try {
269                assertTrue("Method returns false when true is expected",
270                        DESKeySpec.isWeak(semiweaks[i], 0));
271            } catch (InvalidKeyException e) {
272                fail("Unexpected InvalidKeyException was thrown.");
273            }
274        }
275        for (int i=0; i<notsemiweaks.length; i++) {
276            try {
277                assertFalse("Method returns true when false is expected",
278                        DESKeySpec.isWeak(notsemiweaks[i], 0));
279            } catch (InvalidKeyException e) {
280                fail("Unexpected InvalidKeyException was thrown.");
281            }
282        }
283    }
284
285    public static Test suite() {
286        return new TestSuite(DESKeySpecTest.class);
287    }
288
289}
290