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.Arrays;
24  
25  import javax.security.auth.kerberos.KerberosKey;
26  import javax.security.auth.kerberos.KerberosPrincipal;
27  
28  import junit.framework.TestCase;
29  
30  
31  /**
32   * Tests the use of Triple DES for Kerberos, using test vectors from RFC 3961,
33   * "Encryption and Checksum Specifications for Kerberos 5."
34   *
35   * @author <a href="mailto:dev@directory.apache.org">Apache Directory Project</a>
36   * @version $Rev$, $Date$
37   */
38  public class Des3CbcSha1KdEncryptionTest extends TestCase
39  {
40      private Des3CbcSha1KdEncryption keyDerivationFunction = new Des3CbcSha1KdEncryption();
41  
42  
43      /**
44       * Tests setting parity as defined in RFC 3961.
45       */
46      public void testParity()
47      {
48          byte[] test =
49              { ( byte ) 0x93, ( byte ) 0x50, ( byte ) 0x79, ( byte ) 0xd1, ( byte ) 0x44, ( byte ) 0x90, ( byte ) 0xa7 };
50          byte[] expected =
51              { ( byte ) 0x92, ( byte ) 0x51, ( byte ) 0x79, ( byte ) 0xd0, ( byte ) 0x45, ( byte ) 0x91, ( byte ) 0xa7,
52                  ( byte ) 0x9b };
53  
54          byte[] result = keyDerivationFunction.setParity( test );
55  
56          assertTrue( Arrays.equals( expected, result ) );
57      }
58  
59  
60      /**
61       * Tests 'deriveRandom' and 'randomToKey' functions. 
62       */
63      public void testDerivedKey()
64      {
65          byte[] key =
66              { ( byte ) 0xdc, ( byte ) 0xe0, ( byte ) 0x6b, ( byte ) 0x1f, ( byte ) 0x64, ( byte ) 0xc8, ( byte ) 0x57,
67                  ( byte ) 0xa1, ( byte ) 0x1c, ( byte ) 0x3d, ( byte ) 0xb5, ( byte ) 0x7c, ( byte ) 0x51,
68                  ( byte ) 0x89, ( byte ) 0x9b, ( byte ) 0x2c, ( byte ) 0xc1, ( byte ) 0x79, ( byte ) 0x10,
69                  ( byte ) 0x08, ( byte ) 0xce, ( byte ) 0x97, ( byte ) 0x3b, ( byte ) 0x92 };
70  
71          byte[] usage =
72              { ( byte ) 0x00, ( byte ) 0x00, ( byte ) 0x00, ( byte ) 0x01, ( byte ) 0x55 };
73  
74          byte[] DR =
75              { ( byte ) 0x93, ( byte ) 0x50, ( byte ) 0x79, ( byte ) 0xd1, ( byte ) 0x44, ( byte ) 0x90, ( byte ) 0xa7,
76                  ( byte ) 0x5c, ( byte ) 0x30, ( byte ) 0x93, ( byte ) 0xc4, ( byte ) 0xa6, ( byte ) 0xe8,
77                  ( byte ) 0xc3, ( byte ) 0xb0, ( byte ) 0x49, ( byte ) 0xc7, ( byte ) 0x1e, ( byte ) 0x6e,
78                  ( byte ) 0xe7, ( byte ) 0x05 };
79  
80          byte[] DK =
81              { ( byte ) 0x92, ( byte ) 0x51, ( byte ) 0x79, ( byte ) 0xd0, ( byte ) 0x45, ( byte ) 0x91, ( byte ) 0xa7,
82                  ( byte ) 0x9b, ( byte ) 0x5d, ( byte ) 0x31, ( byte ) 0x92, ( byte ) 0xc4, ( byte ) 0xa7,
83                  ( byte ) 0xe9, ( byte ) 0xc2, ( byte ) 0x89, ( byte ) 0xb0, ( byte ) 0x49, ( byte ) 0xc7,
84                  ( byte ) 0x1f, ( byte ) 0x6e, ( byte ) 0xe6, ( byte ) 0x04, ( byte ) 0xcd };
85  
86          byte[] result = keyDerivationFunction.deriveRandom( key, usage, 64, 168 );
87          assertTrue( Arrays.equals( DR, result ) );
88  
89          result = keyDerivationFunction.randomToKey( result );
90          assertTrue( Arrays.equals( DK, result ) );
91      }
92  
93  
94      /**
95       * Tests 'deriveRandom' and 'randomToKey' functions. 
96       */
97      public void testDerivedKey2()
98      {
99          byte[] key =
100             { ( byte ) 0x5e, ( byte ) 0x13, ( byte ) 0xd3, ( byte ) 0x1c, ( byte ) 0x70, ( byte ) 0xef, ( byte ) 0x76,
101                 ( byte ) 0x57, ( byte ) 0x46, ( byte ) 0x57, ( byte ) 0x85, ( byte ) 0x31, ( byte ) 0xcb,
102                 ( byte ) 0x51, ( byte ) 0xc1, ( byte ) 0x5b, ( byte ) 0xf1, ( byte ) 0x1c, ( byte ) 0xa8,
103                 ( byte ) 0x2c, ( byte ) 0x97, ( byte ) 0xce, ( byte ) 0xe9, ( byte ) 0xf2 };
104 
105         byte[] usage =
106             { ( byte ) 0x00, ( byte ) 0x00, ( byte ) 0x00, ( byte ) 0x01, ( byte ) 0xaa };
107 
108         byte[] DR =
109             { ( byte ) 0x9f, ( byte ) 0x58, ( byte ) 0xe5, ( byte ) 0xa0, ( byte ) 0x47, ( byte ) 0xd8, ( byte ) 0x94,
110                 ( byte ) 0x10, ( byte ) 0x1c, ( byte ) 0x46, ( byte ) 0x98, ( byte ) 0x45, ( byte ) 0xd6,
111                 ( byte ) 0x7a, ( byte ) 0xe3, ( byte ) 0xc5, ( byte ) 0x24, ( byte ) 0x9e, ( byte ) 0xd8,
112                 ( byte ) 0x12, ( byte ) 0xf2 };
113 
114         byte[] DK =
115             { ( byte ) 0x9e, ( byte ) 0x58, ( byte ) 0xe5, ( byte ) 0xa1, ( byte ) 0x46, ( byte ) 0xd9, ( byte ) 0x94,
116                 ( byte ) 0x2a, ( byte ) 0x10, ( byte ) 0x1c, ( byte ) 0x46, ( byte ) 0x98, ( byte ) 0x45,
117                 ( byte ) 0xd6, ( byte ) 0x7a, ( byte ) 0x20, ( byte ) 0xe3, ( byte ) 0xc4, ( byte ) 0x25,
118                 ( byte ) 0x9e, ( byte ) 0xd9, ( byte ) 0x13, ( byte ) 0xf2, ( byte ) 0x07 };
119 
120         byte[] result = keyDerivationFunction.deriveRandom( key, usage, 64, 168 );
121         assertTrue( Arrays.equals( DR, result ) );
122 
123         result = keyDerivationFunction.randomToKey( result );
124         assertTrue( Arrays.equals( DK, result ) );
125     }
126 
127 
128     /**
129      * Tests that key derivation can be performed for a Triple-DES key.
130      */
131     public void testTestVectorsTripleDesKerberosKey1()
132     {
133         byte[] expectedKey =
134             { ( byte ) 0x85, ( byte ) 0x0B, ( byte ) 0xB5, ( byte ) 0x13, ( byte ) 0x58, ( byte ) 0x54, ( byte ) 0x8C,
135                 ( byte ) 0xD0, ( byte ) 0x5E, ( byte ) 0x86, ( byte ) 0x76, ( byte ) 0x8C, ( byte ) 0x31,
136                 ( byte ) 0x3E, ( byte ) 0x3B, ( byte ) 0xFE, ( byte ) 0xF7, ( byte ) 0x51, ( byte ) 0x19,
137                 ( byte ) 0x37, ( byte ) 0xDC, ( byte ) 0xF7, ( byte ) 0x2C, ( byte ) 0x3E };
138 
139         KerberosPrincipal principal = new KerberosPrincipal( "raeburn@ATHENA.MIT.EDU" );
140         String algorithm = VendorHelper.getTripleDesAlgorithm();
141         KerberosKey key = new KerberosKey( principal, "password".toCharArray(), algorithm );
142 
143         assertEquals( "DESede key length", 24, key.getEncoded().length );
144         assertTrue( "Key match", Arrays.equals( expectedKey, key.getEncoded() ) );
145     }
146 
147 
148     /**
149      * Tests that key derivation can be performed for a Triple-DES key.
150      */
151     public void testTestVectorsTripleDesKerberosKey2()
152     {
153         byte[] expectedKey =
154             { ( byte ) 0xDF, ( byte ) 0xCD, ( byte ) 0x23, ( byte ) 0x3D, ( byte ) 0xD0, ( byte ) 0xA4, ( byte ) 0x32,
155                 ( byte ) 0x04, ( byte ) 0xEA, ( byte ) 0x6D, ( byte ) 0xC4, ( byte ) 0x37, ( byte ) 0xFB,
156                 ( byte ) 0x15, ( byte ) 0xE0, ( byte ) 0x61, ( byte ) 0xB0, ( byte ) 0x29, ( byte ) 0x79,
157                 ( byte ) 0xC1, ( byte ) 0xF7, ( byte ) 0x4F, ( byte ) 0x37, ( byte ) 0x7A };
158 
159         KerberosPrincipal principal = new KerberosPrincipal( "danny@WHITEHOUSE.GOV" );
160         String algorithm = VendorHelper.getTripleDesAlgorithm();
161         KerberosKey key = new KerberosKey( principal, "potatoe".toCharArray(), algorithm );
162 
163         assertEquals( "DESede key length", 24, key.getEncoded().length );
164         assertTrue( "Key match", Arrays.equals( expectedKey, key.getEncoded() ) );
165     }
166 
167 
168     /**
169      * Tests that key derivation can be performed for a Triple-DES key.
170      */
171     public void testTestVectorsTripleDesKerberosKey3()
172     {
173         byte[] expectedKey =
174             { ( byte ) 0x6D, ( byte ) 0x2F, ( byte ) 0xCD, ( byte ) 0xF2, ( byte ) 0xD6, ( byte ) 0xFB, ( byte ) 0xBC,
175                 ( byte ) 0x3D, ( byte ) 0xDC, ( byte ) 0xAD, ( byte ) 0xB5, ( byte ) 0xDA, ( byte ) 0x57,
176                 ( byte ) 0x10, ( byte ) 0xA2, ( byte ) 0x34, ( byte ) 0x89, ( byte ) 0xB0, ( byte ) 0xD3,
177                 ( byte ) 0xB6, ( byte ) 0x9D, ( byte ) 0x5D, ( byte ) 0x9D, ( byte ) 0x4A };
178 
179         KerberosPrincipal principal = new KerberosPrincipal( "buckaroo@EXAMPLE.COM" );
180         String algorithm = VendorHelper.getTripleDesAlgorithm();
181         KerberosKey key = new KerberosKey( principal, "penny".toCharArray(), algorithm );
182 
183         assertEquals( "DESede key length", 24, key.getEncoded().length );
184         assertTrue( "Key match", Arrays.equals( expectedKey, key.getEncoded() ) );
185     }
186 
187 
188     /**
189      * Tests that key derivation can be performed for a Triple-DES key.
190      */
191     public void testTestVectorsTripleDesKerberosKey4()
192     {
193         if ( VendorHelper.isIbm() )
194         {
195             return;
196         }
197 
198         byte[] expectedKey =
199             { ( byte ) 0x16, ( byte ) 0xD5, ( byte ) 0xA4, ( byte ) 0x0E, ( byte ) 0x1C, ( byte ) 0xE3, ( byte ) 0xBA,
200                 ( byte ) 0xCB, ( byte ) 0x61, ( byte ) 0xB9, ( byte ) 0xDC, ( byte ) 0xE0, ( byte ) 0x04,
201                 ( byte ) 0x70, ( byte ) 0x32, ( byte ) 0x4C, ( byte ) 0x83, ( byte ) 0x19, ( byte ) 0x73,
202                 ( byte ) 0xA7, ( byte ) 0xB9, ( byte ) 0x52, ( byte ) 0xFE, ( byte ) 0xB0 };
203 
204         KerberosPrincipal principal = new KerberosPrincipal( "Juri\u0161i\u0107@ATHENA.MIT.EDU" );
205         String algorithm = VendorHelper.getTripleDesAlgorithm();
206         KerberosKey key = new KerberosKey( principal, "\u00DF".toCharArray(), algorithm );
207 
208         assertEquals( "DESede key length", 24, key.getEncoded().length );
209         assertTrue( "Key match", Arrays.equals( expectedKey, key.getEncoded() ) );
210     }
211 
212 
213     /**
214      * Tests that key derivation can be performed for a Triple-DES key.
215      */
216     public void testTestVectorsTripleDesKerberosKey5()
217     {
218         if ( VendorHelper.isIbm() )
219         {
220             return;
221         }
222 
223         byte[] expectedKey =
224             { ( byte ) 0x85, ( byte ) 0x76, ( byte ) 0x37, ( byte ) 0x26, ( byte ) 0x58, ( byte ) 0x5D, ( byte ) 0xBC,
225                 ( byte ) 0x1C, ( byte ) 0xCE, ( byte ) 0x6E, ( byte ) 0xC4, ( byte ) 0x3E, ( byte ) 0x1F,
226                 ( byte ) 0x75, ( byte ) 0x1F, ( byte ) 0x07, ( byte ) 0xF1, ( byte ) 0xC4, ( byte ) 0xCB,
227                 ( byte ) 0xB0, ( byte ) 0x98, ( byte ) 0xF4, ( byte ) 0x0B, ( byte ) 0x19 };
228 
229         KerberosPrincipal principal = new KerberosPrincipal( "pianist@EXAMPLE.COM" );
230         String algorithm = VendorHelper.getTripleDesAlgorithm();
231         KerberosKey key = new KerberosKey( principal, "\uD834\uDD1E".toCharArray(), algorithm );
232 
233         assertEquals( "DESede key length", 24, key.getEncoded().length );
234         assertTrue( "Key match", Arrays.equals( expectedKey, key.getEncoded() ) );
235     }
236 }