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
18package org.apache.harmony.auth.tests.javax.security.auth.kerberos;
19
20import java.io.ByteArrayOutputStream;
21import java.io.IOException;
22import java.io.ObjectOutputStream;
23import java.util.Arrays;
24
25import javax.security.auth.DestroyFailedException;
26import javax.security.auth.kerberos.KerberosKey;
27import javax.security.auth.kerberos.KerberosPrincipal;
28
29import junit.framework.TestCase;
30
31/**
32 * Tests KerberosKey class implementation.
33 *
34 * @see http://www.ietf.org/rfc/rfc3961.txt
35 */
36public class KerberosKeyTest extends TestCase {
37
38    // principal object for testing
39    private final KerberosPrincipal principal = new KerberosPrincipal(
40            "name@aaa.com", 1);
41
42    // byte array for testing
43    private final byte[] keyBytes = new byte[] { 0x00, 0x01, 0x02, 0x03, 0x04,
44            0x05, 0x06, 0x07 };
45
46    /**
47     * @tests javax.security.auth.kerberos.KerberosKey#KerberosKey(
48     *        javax.security.auth.kerberos.KerberosPrincipal, byte[], int, int)
49     */
50    public void test_Ctor1() {
51
52        // OK to pass null value for principal parameter
53        assertNull(new KerberosKey(null, keyBytes, 0, 0).getPrincipal());
54
55        // NPE for null keyBytes parameter
56        try {
57            new KerberosKey(principal, null, 0, 0);
58            fail("No expected NullPointerException");
59        } catch (NullPointerException e) {
60        }
61
62        // construct with DES algorithm
63        KerberosKey key = new KerberosKey(principal, keyBytes, 1, 123);
64        assertEquals("DES algorithm", "DES", key.getAlgorithm());
65        assertEquals("version number", 123, key.getVersionNumber());
66        assertEquals("format", "RAW", key.getFormat());
67        assertSame("principal", principal, key.getPrincipal());
68        assertFalse("is destroyed", key.isDestroyed());
69
70        // construct with NULL algorithm
71        key = new KerberosKey(principal, keyBytes, 0, 0);
72        assertEquals("NULL algorithm", "NULL", key.getAlgorithm());
73        assertEquals("version number", 0, key.getVersionNumber());
74    }
75
76    /**
77     * @tests javax.security.auth.kerberos.KerberosKey#KerberosKey(
78     *        javax.security.auth.kerberos.KerberosPrincipal, char[],
79     *        java.lang.String)
80     */
81    public void test_Ctor2() {
82
83        // NPE for null value for principal parameter
84        try {
85            new KerberosKey(null, new char[10], "DES");
86            fail("No expected NullPointerException");
87        } catch (NullPointerException e) {
88        }
89
90        // NPE for null password value
91        try {
92            new KerberosKey(principal, null, "DES");
93            fail("No expected NullPointerException");
94        } catch (NullPointerException e) {
95        }
96
97        // IAE for unsupported algorithm
98        try {
99            new KerberosKey(principal, new char[10],
100                    "there_is_no_such_algorithm");
101            fail("No expected IllegalArgumentException");
102        } catch (IllegalArgumentException e) {
103        }
104
105        // if algorithm parameter is null then DES is used
106        KerberosKey key = new KerberosKey(principal, new char[10], null);
107
108        assertEquals("algorithm", "DES", key.getAlgorithm());
109        assertEquals("format", "RAW", key.getFormat());
110        assertEquals("key type", 3, key.getKeyType());
111        assertEquals("version number", 0, key.getVersionNumber());
112        assertFalse("is destroyed", key.isDestroyed());
113        assertSame("principal", principal, key.getPrincipal());
114    }
115
116    /**
117     * @tests javax.security.auth.kerberos.KerberosKey#getEncoded()
118     */
119    public void test_getEncoded() {
120
121        KerberosKey key = new KerberosKey(principal, keyBytes, 1, 123);
122
123        byte[] keyBytes1 = key.getEncoded();
124        assertTrue("encoded", Arrays.equals(keyBytes, keyBytes1));
125
126        // bytes are copied each time we invoke the method
127        assertNotSame("keyBytes immutability 1 ", keyBytes, keyBytes1);
128        assertNotSame("keyBytes immutability 2 ", keyBytes1, key.getEncoded());
129
130        // Test generation of DES key from password
131        // test data from RFC 3961 (http://www.ietf.org/rfc/rfc3961.txt)
132        // see A.2 test vectors
133        // test data format: principal/password/DES key
134        Object[][] testcases = {
135                {
136                        "raeburn@ATHENA.MIT.EDU",
137                        "password",
138                        new byte[] { (byte) 0xcb, (byte) 0xc2, (byte) 0x2f,
139                                (byte) 0xae, (byte) 0x23, (byte) 0x52,
140                                (byte) 0x98, (byte) 0xe3 } },
141                {
142                        "danny@WHITEHOUSE.GOV",
143                        "potatoe",
144                        new byte[] { (byte) 0xdf, (byte) 0x3d, (byte) 0x32,
145                                (byte) 0xa7, (byte) 0x4f, (byte) 0xd9,
146                                (byte) 0x2a, (byte) 0x01 } },
147        // TODO add "pianist@EXAMPLE.COM" and "Juri ... @ATHENA.MIT.EDU"
148        };
149
150        for (Object[] element : testcases) {
151            KerberosPrincipal kp = new KerberosPrincipal(
152                    (String) element[0], 1);
153
154            key = new KerberosKey(kp, ((String) element[1]).toCharArray(),
155                    "DES");
156
157            assertTrue("Testcase: " + (String) element[0], Arrays.equals(
158                    (byte[]) element[2], key.getEncoded()));
159        }
160    }
161
162    /**
163     * @tests javax.security.auth.kerberos.KerberosKey#destroy()
164     */
165    public void test_destroy() throws Exception {
166
167        KerberosKey key = new KerberosKey(principal, new char[10], "DES");
168
169        assertFalse("not destroyed", key.isDestroyed());
170
171        key.destroy();
172        assertTrue("destroyed", key.isDestroyed());
173
174        // no exceptions for second destroy() call
175        key.destroy();
176
177        // check that IllegalStateException is thrown for certain methods
178        try {
179            key.getAlgorithm();
180            fail("No expected IllegalStateException");
181        } catch (IllegalStateException e) {
182        }
183
184        try {
185            key.getEncoded();
186            fail("No expected IllegalStateException");
187        } catch (IllegalStateException e) {
188        }
189
190        try {
191            key.getFormat();
192            fail("No expected IllegalStateException");
193        } catch (IllegalStateException e) {
194        }
195
196        try {
197            key.getKeyType();
198            fail("No expected IllegalStateException");
199        } catch (IllegalStateException e) {
200        }
201
202        try {
203            key.getPrincipal();
204            fail("No expected IllegalStateException");
205        } catch (IllegalStateException e) {
206        }
207
208        try {
209            key.getVersionNumber();
210            fail("No expected IllegalStateException");
211        } catch (IllegalStateException e) {
212        }
213
214        try {
215            // but for serialization IOException is expected
216            ObjectOutputStream out = new ObjectOutputStream(
217                    new ByteArrayOutputStream());
218            out.writeObject(key);
219            fail("No expected IOException");
220        } catch (IOException e) {
221        }
222
223        try {
224            key.toString();
225            fail("No expected IllegalStateException");
226        } catch (IllegalStateException e) {
227        }
228    }
229
230    /**
231     * @tests javax.security.auth.kerberos.KerberosKey#equals(java.lang.Object)
232     */
233    public void test_equals() {
234        KerberosKey kerberosKey1 = new KerberosKey(principal, keyBytes, 1, 123);
235        KerberosKey kerberosKey2 = new KerberosKey(principal, keyBytes, 1, 123);
236        KerberosKey kerberosKey3 = new KerberosKey(principal, new byte[] { 1,
237                3, 4, 5 }, 1, 123);
238        assertEquals("kerberosKey1 and kerberosKey2 should be equivalent ",
239                kerberosKey1, kerberosKey2);
240        assertFalse("kerberosKey1 and kerberosKey3 sholudn't be equivalent ",
241                kerberosKey1.equals(kerberosKey3));
242        try {
243            kerberosKey2.destroy();
244        } catch (DestroyFailedException e) {
245            fail("kerberosKey2 destroy failed");
246        }
247        assertFalse("Destroyed kerberosKey sholudn't be equivalent ",
248                kerberosKey1.equals(kerberosKey2));
249    }
250
251    /**
252     * @tests javax.security.auth.kerberos.KerberosKey#hashCode()
253     */
254    public void test_hashCode() {
255        KerberosKey kerberosKey1 = new KerberosKey(principal, keyBytes, 1, 123);
256        KerberosKey kerberosKey2 = new KerberosKey(principal, keyBytes, 1, 123);
257        assertEquals("kerberosKey1 and kerberosKey2 should be equivalent ",
258                kerberosKey1, kerberosKey2);
259        assertEquals("hashCode should be equivalent", kerberosKey1.hashCode(),
260                kerberosKey2.hashCode());
261    }
262}
263