1   /*
2    *  Licensed to the Apache Software Foundation (ASF) under one
3    *  or more contributor license agreements.  See the NOTICE file
4    *  distributed with this work for additional information
5    *  regarding copyright ownership.  The ASF licenses this file
6    *  to you under the Apache License, Version 2.0 (the
7    *  "License"); you may not use this file except in compliance
8    *  with the License.  You may obtain a copy of the License at
9    *  
10   *    http://www.apache.org/licenses/LICENSE-2.0
11   *  
12   *  Unless required by applicable law or agreed to in writing,
13   *  software distributed under the License is distributed on an
14   *  "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
15   *  KIND, either express or implied.  See the License for the
16   *  specific language governing permissions and limitations
17   *  under the License. 
18   *  
19   */
20  package org.apache.directory.server.kerberos.shared.crypto.encryption;
21  
22  
23  import java.util.HashSet;
24  import java.util.Map;
25  import java.util.Set;
26  
27  import javax.crypto.KeyGenerator;
28  import javax.crypto.SecretKey;
29  import javax.crypto.spec.DESKeySpec;
30  
31  import junit.framework.TestCase;
32  
33  import org.apache.directory.server.kerberos.shared.messages.value.EncryptionKey;
34  
35  
36  /**
37   * Test cases for random-to-key functions for DES-, DES3-, AES-, and RC4-based
38   * encryption types.
39   * 
40   * @author <a href="mailto:dev@directory.apache.org">Apache Directory Project</a>
41   * @version $Rev$, $Date$
42   */
43  public class RandomKeyFactoryTest extends TestCase
44  {
45      /**
46       * Tests that random DES keys can be generated.
47       *
48       * @throws Exception
49       */
50      public void testGenerateDesKey() throws Exception
51      {
52          KeyGenerator keygen = KeyGenerator.getInstance( "DES" );
53          SecretKey key = keygen.generateKey();
54          assertEquals( "DES key size", 8, key.getEncoded().length );
55          assertTrue( DESKeySpec.isParityAdjusted( key.getEncoded(), 0 ) );
56      }
57  
58  
59      /**
60       * Tests that random Triple-DES keys can be generated.
61       *
62       * @throws Exception
63       */
64      public void testGenerateTripleDesKey() throws Exception
65      {
66          KeyGenerator keygen = KeyGenerator.getInstance( "DESede" );
67          SecretKey key = keygen.generateKey();
68          assertEquals( "DESede key size", 24, key.getEncoded().length );
69      }
70  
71  
72      /**
73       * Tests that random AES128 keys can be generated.
74       *
75       * @throws Exception
76       */
77      public void testGenerateAes128Key() throws Exception
78      {
79          KeyGenerator keygen = KeyGenerator.getInstance( "AES" );
80          keygen.init( 128 );
81          SecretKey key = keygen.generateKey();
82          assertEquals( "AES key size", 16, key.getEncoded().length );
83      }
84  
85  
86      /**
87       * Tests that random AES256 keys can be generated.
88       *
89       * @throws Exception
90       */
91      public void testGenerateAes256Key() throws Exception
92      {
93          KeyGenerator keygen = KeyGenerator.getInstance( "AES" );
94          keygen.init( 256 );
95          SecretKey key = keygen.generateKey();
96          assertEquals( "AES key size", 32, key.getEncoded().length );
97      }
98  
99  
100     /**
101      * Tests that random ARCFOUR keys can be generated.
102      *
103      * @throws Exception
104      */
105     public void testGenerateArcFourKey() throws Exception
106     {
107         if ( !VendorHelper.isArcFourHmacSupported() )
108         {
109             return;
110         }
111 
112         KeyGenerator keygen = KeyGenerator.getInstance( "ARCFOUR" );
113         SecretKey key = keygen.generateKey();
114         assertEquals( "ARCFOUR key size", 16, key.getEncoded().length );
115     }
116 
117 
118     /**
119      * Tests that random RC4 keys can be generated.
120      *
121      * @throws Exception
122      */
123     public void testGenerateRc4Key() throws Exception
124     {
125         if ( !VendorHelper.isArcFourHmacSupported() )
126         {
127             return;
128         }
129 
130         KeyGenerator keygen = KeyGenerator.getInstance( "RC4" );
131         SecretKey key = keygen.generateKey();
132         assertEquals( "RC4 key size", 16, key.getEncoded().length );
133     }
134 
135 
136     /**
137      * Tests that random key generation can be performed by the factory for multiple cipher types.
138      * 
139      * @throws Exception
140      */
141     public void testRandomKeyFactory() throws Exception
142     {
143         Map<EncryptionType, EncryptionKey> map = RandomKeyFactory.getRandomKeys();
144 
145         EncryptionKey kerberosKey = map.get( EncryptionType.DES_CBC_MD5 );
146 
147         EncryptionType keyType = kerberosKey.getKeyType();
148         int keyLength = kerberosKey.getKeyValue().length;
149 
150         assertEquals( keyType, EncryptionType.DES_CBC_MD5 );
151         assertEquals( keyLength, 8 );
152 
153         kerberosKey = map.get( EncryptionType.DES3_CBC_SHA1_KD );
154         keyType = kerberosKey.getKeyType();
155         keyLength = kerberosKey.getKeyValue().length;
156 
157         assertEquals( keyType, EncryptionType.DES3_CBC_SHA1_KD );
158         assertEquals( keyLength, 24 );
159 
160         kerberosKey = map.get( EncryptionType.RC4_HMAC );
161         keyType = kerberosKey.getKeyType();
162         keyLength = kerberosKey.getKeyValue().length;
163 
164         if ( VendorHelper.isArcFourHmacSupported() )
165         {
166             assertEquals( keyType, EncryptionType.RC4_HMAC );
167             assertEquals( keyLength, 16 );
168         }
169 
170         kerberosKey = map.get( EncryptionType.AES128_CTS_HMAC_SHA1_96 );
171         keyType = kerberosKey.getKeyType();
172         keyLength = kerberosKey.getKeyValue().length;
173 
174         assertEquals( keyType, EncryptionType.AES128_CTS_HMAC_SHA1_96 );
175         assertEquals( keyLength, 16 );
176 
177         kerberosKey = map.get( EncryptionType.AES256_CTS_HMAC_SHA1_96 );
178         keyType = kerberosKey.getKeyType();
179         keyLength = kerberosKey.getKeyValue().length;
180 
181         assertEquals( keyType, EncryptionType.AES256_CTS_HMAC_SHA1_96 );
182         assertEquals( keyLength, 32 );
183     }
184 
185 
186     /**
187      * Tests that random key generation can be performed by the factory for a specified cipher type.
188      * 
189      * @throws Exception
190      */
191     public void testRandomKeyFactoryOnlyDes() throws Exception
192     {
193         Set<EncryptionType> encryptionTypes = new HashSet<EncryptionType>();
194         encryptionTypes.add( EncryptionType.DES_CBC_MD5 );
195 
196         Map<EncryptionType, EncryptionKey> map = RandomKeyFactory.getRandomKeys( encryptionTypes );
197 
198         assertEquals( "List length", 1, map.values().size() );
199 
200         EncryptionKey kerberosKey = map.get( EncryptionType.DES_CBC_MD5 );
201 
202         EncryptionType keyType = kerberosKey.getKeyType();
203         int keyLength = kerberosKey.getKeyValue().length;
204 
205         assertEquals( keyType, EncryptionType.DES_CBC_MD5 );
206         assertEquals( keyLength, 8 );
207     }
208 }