blob: 15693c9678e8df9d27f1f02e8332d07810496dcc [file] [log] [blame]
/*
* Licensed to the Apache Software Foundation (ASF) under one
* or more contributor license agreements. See the NOTICE file
* distributed with this work for additional information
* regarding copyright ownership. The ASF licenses this file
* to you under the Apache License, Version 2.0 (the
* "License"); you may not use this file except in compliance
* with the License. You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing,
* software distributed under the License is distributed on an
* "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
* KIND, either express or implied. See the License for the
* specific language governing permissions and limitations
* under the License.
*
*/
package org.apache.directory.server.kerberos.shared.crypto.encryption;
import java.util.Arrays;
import javax.security.auth.kerberos.KerberosKey;
import javax.security.auth.kerberos.KerberosPrincipal;
import com.mycila.junit.concurrent.Concurrency;
import com.mycila.junit.concurrent.ConcurrentJunitRunner;
import org.junit.Test;
import org.junit.runner.RunWith;
import static org.junit.Assert.assertEquals;
import static org.junit.Assert.assertTrue;
/**
* Tests the use of Triple DES for Kerberos, using test vectors from RFC 3961,
* "Encryption and Checksum Specifications for Kerberos 5."
*
* @author <a href="mailto:dev@directory.apache.org">Apache Directory Project</a>
*/
@RunWith(ConcurrentJunitRunner.class)
@Concurrency()
public class Des3CbcSha1KdEncryptionTest
{
private static final Des3CbcSha1KdEncryption keyDerivationFunction = new Des3CbcSha1KdEncryption();
/**
* Tests setting parity as defined in RFC 3961.
*/
@Test
public void testParity()
{
byte[] test =
{ ( byte ) 0x93, ( byte ) 0x50, ( byte ) 0x79, ( byte ) 0xd1, ( byte ) 0x44, ( byte ) 0x90, ( byte ) 0xa7 };
byte[] expected =
{ ( byte ) 0x92, ( byte ) 0x51, ( byte ) 0x79, ( byte ) 0xd0, ( byte ) 0x45, ( byte ) 0x91, ( byte ) 0xa7,
( byte ) 0x9b };
byte[] result = keyDerivationFunction.setParity( test );
assertTrue( Arrays.equals( expected, result ) );
}
/**
* Tests 'deriveRandom' and 'randomToKey' functions.
*/
@Test
public void testDerivedKey()
{
byte[] key =
{ ( byte ) 0xdc, ( byte ) 0xe0, ( byte ) 0x6b, ( byte ) 0x1f, ( byte ) 0x64, ( byte ) 0xc8, ( byte ) 0x57,
( byte ) 0xa1, ( byte ) 0x1c, ( byte ) 0x3d, ( byte ) 0xb5, ( byte ) 0x7c, ( byte ) 0x51,
( byte ) 0x89, ( byte ) 0x9b, ( byte ) 0x2c, ( byte ) 0xc1, ( byte ) 0x79, ( byte ) 0x10,
( byte ) 0x08, ( byte ) 0xce, ( byte ) 0x97, ( byte ) 0x3b, ( byte ) 0x92 };
byte[] usage =
{ ( byte ) 0x00, ( byte ) 0x00, ( byte ) 0x00, ( byte ) 0x01, ( byte ) 0x55 };
byte[] DR =
{ ( byte ) 0x93, ( byte ) 0x50, ( byte ) 0x79, ( byte ) 0xd1, ( byte ) 0x44, ( byte ) 0x90, ( byte ) 0xa7,
( byte ) 0x5c, ( byte ) 0x30, ( byte ) 0x93, ( byte ) 0xc4, ( byte ) 0xa6, ( byte ) 0xe8,
( byte ) 0xc3, ( byte ) 0xb0, ( byte ) 0x49, ( byte ) 0xc7, ( byte ) 0x1e, ( byte ) 0x6e,
( byte ) 0xe7, ( byte ) 0x05 };
byte[] DK =
{ ( byte ) 0x92, ( byte ) 0x51, ( byte ) 0x79, ( byte ) 0xd0, ( byte ) 0x45, ( byte ) 0x91, ( byte ) 0xa7,
( byte ) 0x9b, ( byte ) 0x5d, ( byte ) 0x31, ( byte ) 0x92, ( byte ) 0xc4, ( byte ) 0xa7,
( byte ) 0xe9, ( byte ) 0xc2, ( byte ) 0x89, ( byte ) 0xb0, ( byte ) 0x49, ( byte ) 0xc7,
( byte ) 0x1f, ( byte ) 0x6e, ( byte ) 0xe6, ( byte ) 0x04, ( byte ) 0xcd };
byte[] result = keyDerivationFunction.deriveRandom( key, usage, 64, 168 );
assertTrue( Arrays.equals( DR, result ) );
result = keyDerivationFunction.randomToKey( result );
assertTrue( Arrays.equals( DK, result ) );
}
/**
* Tests 'deriveRandom' and 'randomToKey' functions.
*/
@Test
public void testDerivedKey2()
{
byte[] key =
{ ( byte ) 0x5e, ( byte ) 0x13, ( byte ) 0xd3, ( byte ) 0x1c, ( byte ) 0x70, ( byte ) 0xef, ( byte ) 0x76,
( byte ) 0x57, ( byte ) 0x46, ( byte ) 0x57, ( byte ) 0x85, ( byte ) 0x31, ( byte ) 0xcb,
( byte ) 0x51, ( byte ) 0xc1, ( byte ) 0x5b, ( byte ) 0xf1, ( byte ) 0x1c, ( byte ) 0xa8,
( byte ) 0x2c, ( byte ) 0x97, ( byte ) 0xce, ( byte ) 0xe9, ( byte ) 0xf2 };
byte[] usage =
{ ( byte ) 0x00, ( byte ) 0x00, ( byte ) 0x00, ( byte ) 0x01, ( byte ) 0xaa };
byte[] DR =
{ ( byte ) 0x9f, ( byte ) 0x58, ( byte ) 0xe5, ( byte ) 0xa0, ( byte ) 0x47, ( byte ) 0xd8, ( byte ) 0x94,
( byte ) 0x10, ( byte ) 0x1c, ( byte ) 0x46, ( byte ) 0x98, ( byte ) 0x45, ( byte ) 0xd6,
( byte ) 0x7a, ( byte ) 0xe3, ( byte ) 0xc5, ( byte ) 0x24, ( byte ) 0x9e, ( byte ) 0xd8,
( byte ) 0x12, ( byte ) 0xf2 };
byte[] DK =
{ ( byte ) 0x9e, ( byte ) 0x58, ( byte ) 0xe5, ( byte ) 0xa1, ( byte ) 0x46, ( byte ) 0xd9, ( byte ) 0x94,
( byte ) 0x2a, ( byte ) 0x10, ( byte ) 0x1c, ( byte ) 0x46, ( byte ) 0x98, ( byte ) 0x45,
( byte ) 0xd6, ( byte ) 0x7a, ( byte ) 0x20, ( byte ) 0xe3, ( byte ) 0xc4, ( byte ) 0x25,
( byte ) 0x9e, ( byte ) 0xd9, ( byte ) 0x13, ( byte ) 0xf2, ( byte ) 0x07 };
byte[] result = keyDerivationFunction.deriveRandom( key, usage, 64, 168 );
assertTrue( Arrays.equals( DR, result ) );
result = keyDerivationFunction.randomToKey( result );
assertTrue( Arrays.equals( DK, result ) );
}
/**
* Tests that key derivation can be performed for a Triple-DES key.
*/
@Test
public void testTestVectorsTripleDesKerberosKey1()
{
byte[] expectedKey =
{ ( byte ) 0x85, ( byte ) 0x0B, ( byte ) 0xB5, ( byte ) 0x13, ( byte ) 0x58, ( byte ) 0x54, ( byte ) 0x8C,
( byte ) 0xD0, ( byte ) 0x5E, ( byte ) 0x86, ( byte ) 0x76, ( byte ) 0x8C, ( byte ) 0x31,
( byte ) 0x3E, ( byte ) 0x3B, ( byte ) 0xFE, ( byte ) 0xF7, ( byte ) 0x51, ( byte ) 0x19,
( byte ) 0x37, ( byte ) 0xDC, ( byte ) 0xF7, ( byte ) 0x2C, ( byte ) 0x3E };
KerberosPrincipal principal = new KerberosPrincipal( "raeburn@ATHENA.MIT.EDU" );
String algorithm = VendorHelper.getTripleDesAlgorithm();
KerberosKey key = new KerberosKey( principal, "password".toCharArray(), algorithm );
assertEquals( "DESede key length", 24, key.getEncoded().length );
assertTrue( "Key match", Arrays.equals( expectedKey, key.getEncoded() ) );
}
/**
* Tests that key derivation can be performed for a Triple-DES key.
*/
@Test
public void testTestVectorsTripleDesKerberosKey2()
{
byte[] expectedKey =
{ ( byte ) 0xDF, ( byte ) 0xCD, ( byte ) 0x23, ( byte ) 0x3D, ( byte ) 0xD0, ( byte ) 0xA4, ( byte ) 0x32,
( byte ) 0x04, ( byte ) 0xEA, ( byte ) 0x6D, ( byte ) 0xC4, ( byte ) 0x37, ( byte ) 0xFB,
( byte ) 0x15, ( byte ) 0xE0, ( byte ) 0x61, ( byte ) 0xB0, ( byte ) 0x29, ( byte ) 0x79,
( byte ) 0xC1, ( byte ) 0xF7, ( byte ) 0x4F, ( byte ) 0x37, ( byte ) 0x7A };
KerberosPrincipal principal = new KerberosPrincipal( "danny@WHITEHOUSE.GOV" );
String algorithm = VendorHelper.getTripleDesAlgorithm();
KerberosKey key = new KerberosKey( principal, "potatoe".toCharArray(), algorithm );
assertEquals( "DESede key length", 24, key.getEncoded().length );
assertTrue( "Key match", Arrays.equals( expectedKey, key.getEncoded() ) );
}
/**
* Tests that key derivation can be performed for a Triple-DES key.
*/
@Test
public void testTestVectorsTripleDesKerberosKey3()
{
byte[] expectedKey =
{ ( byte ) 0x6D, ( byte ) 0x2F, ( byte ) 0xCD, ( byte ) 0xF2, ( byte ) 0xD6, ( byte ) 0xFB, ( byte ) 0xBC,
( byte ) 0x3D, ( byte ) 0xDC, ( byte ) 0xAD, ( byte ) 0xB5, ( byte ) 0xDA, ( byte ) 0x57,
( byte ) 0x10, ( byte ) 0xA2, ( byte ) 0x34, ( byte ) 0x89, ( byte ) 0xB0, ( byte ) 0xD3,
( byte ) 0xB6, ( byte ) 0x9D, ( byte ) 0x5D, ( byte ) 0x9D, ( byte ) 0x4A };
KerberosPrincipal principal = new KerberosPrincipal( "buckaroo@EXAMPLE.COM" );
String algorithm = VendorHelper.getTripleDesAlgorithm();
KerberosKey key = new KerberosKey( principal, "penny".toCharArray(), algorithm );
assertEquals( "DESede key length", 24, key.getEncoded().length );
assertTrue( "Key match", Arrays.equals( expectedKey, key.getEncoded() ) );
}
/**
* Tests that key derivation can be performed for a Triple-DES key.
*/
@Test
public void testTestVectorsTripleDesKerberosKey4()
{
if ( VendorHelper.isIbm() )
{
return;
}
byte[] expectedKey =
{ ( byte ) 0x16, ( byte ) 0xD5, ( byte ) 0xA4, ( byte ) 0x0E, ( byte ) 0x1C, ( byte ) 0xE3, ( byte ) 0xBA,
( byte ) 0xCB, ( byte ) 0x61, ( byte ) 0xB9, ( byte ) 0xDC, ( byte ) 0xE0, ( byte ) 0x04,
( byte ) 0x70, ( byte ) 0x32, ( byte ) 0x4C, ( byte ) 0x83, ( byte ) 0x19, ( byte ) 0x73,
( byte ) 0xA7, ( byte ) 0xB9, ( byte ) 0x52, ( byte ) 0xFE, ( byte ) 0xB0 };
KerberosPrincipal principal = new KerberosPrincipal( "Juri\u0161i\u0107@ATHENA.MIT.EDU" );
String algorithm = VendorHelper.getTripleDesAlgorithm();
KerberosKey key = new KerberosKey( principal, "\u00DF".toCharArray(), algorithm );
assertEquals( "DESede key length", 24, key.getEncoded().length );
assertTrue( "Key match", Arrays.equals( expectedKey, key.getEncoded() ) );
}
/**
* Tests that key derivation can be performed for a Triple-DES key.
*/
@Test
public void testTestVectorsTripleDesKerberosKey5()
{
if ( VendorHelper.isIbm() )
{
return;
}
byte[] expectedKey =
{ ( byte ) 0x85, ( byte ) 0x76, ( byte ) 0x37, ( byte ) 0x26, ( byte ) 0x58, ( byte ) 0x5D, ( byte ) 0xBC,
( byte ) 0x1C, ( byte ) 0xCE, ( byte ) 0x6E, ( byte ) 0xC4, ( byte ) 0x3E, ( byte ) 0x1F,
( byte ) 0x75, ( byte ) 0x1F, ( byte ) 0x07, ( byte ) 0xF1, ( byte ) 0xC4, ( byte ) 0xCB,
( byte ) 0xB0, ( byte ) 0x98, ( byte ) 0xF4, ( byte ) 0x0B, ( byte ) 0x19 };
KerberosPrincipal principal = new KerberosPrincipal( "pianist@EXAMPLE.COM" );
String algorithm = VendorHelper.getTripleDesAlgorithm();
KerberosKey key = new KerberosKey( principal, "\uD834\uDD1E".toCharArray(), algorithm );
assertEquals( "DESede key length", 24, key.getEncoded().length );
assertTrue( "Key match", Arrays.equals( expectedKey, key.getEncoded() ) );
}
}