blob: e112ff334d40c9dc28c19dcfa62ac9aaed8b7534 [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.security.InvalidKeyException;
import java.util.Arrays;
import javax.crypto.spec.DESKeySpec;
import junit.framework.TestCase;
/**
* Test cases for the DES string-to-key function as described in RFC 3961,
* "Encryption and Checksum Specifications for Kerberos 5."
*
* @author <a href="mailto:dev@directory.apache.org">Apache Directory Project</a>
* @version $Rev$, $Date$
*/
public class DesStringToKeyTest extends TestCase
{
private byte[] fanFold1 =
{ ( byte ) 0xC0, ( byte ) 0x1E, ( byte ) 0x38, ( byte ) 0x68, ( byte ) 0x8A, ( byte ) 0xC8, ( byte ) 0x6C,
( byte ) 0x2E };
private byte[] intermediateKey1 =
{ ( byte ) 0xC1, ( byte ) 0x1F, ( byte ) 0x38, ( byte ) 0x68, ( byte ) 0x8A, ( byte ) 0xC8, ( byte ) 0x6D,
( byte ) 0x2F };
private byte[] desKey1 =
{ ( byte ) 0xCB, ( byte ) 0xC2, ( byte ) 0x2F, ( byte ) 0xAE, ( byte ) 0x23, ( byte ) 0x52, ( byte ) 0x98,
( byte ) 0xE3 };
private byte[] fanFold2 =
{ ( byte ) 0xA0, ( byte ) 0x28, ( byte ) 0x94, ( byte ) 0x4E, ( byte ) 0xE6, ( byte ) 0x3C, ( byte ) 0x04,
( byte ) 0x16 };
private byte[] intermediateKey2 =
{ ( byte ) 0xA1, ( byte ) 0x29, ( byte ) 0x94, ( byte ) 0x4F, ( byte ) 0xE6, ( byte ) 0x3D, ( byte ) 0x04,
( byte ) 0x16 };
private byte[] desKey2 =
{ ( byte ) 0xDF, ( byte ) 0x3D, ( byte ) 0x32, ( byte ) 0xA7, ( byte ) 0x4F, ( byte ) 0xD9, ( byte ) 0x2A,
( byte ) 0x01 };
private DesStringToKey stringToKey = new DesStringToKey();
/**
* Tests DES StringToKey test vector 1 from RFC 3961.
*/
public void testDesStringToKeyVector1()
{
byte[] key = stringToKey.getKey( "password", "ATHENA.MIT.EDU", "raeburn" );
assertTrue( "Key match", Arrays.equals( desKey1, key ) );
}
/**
* Tests DES StringToKey test vector 2 from RFC 3961.
*/
public void testDesStringToKeyVector2()
{
byte[] key = stringToKey.getKey( "potatoe", "WHITEHOUSE.GOV", "danny" );
assertTrue( "Key match", Arrays.equals( desKey2, key ) );
}
/**
* Tests DES StringToKey test vector 1 from RFC 3961 with intermediate step checks.
*
* @throws InvalidKeyException
*/
public void testIntermediateDesStringToKeyVector1() throws InvalidKeyException
{
String passPhrase = "passwordATHENA.MIT.EDUraeburn";
byte[] encodedByteArray = stringToKey.characterEncodeString( passPhrase );
byte[] paddedByteArray = stringToKey.padString( encodedByteArray );
byte[] fanFold = stringToKey.fanFold( paddedByteArray );
assertTrue( "Key match", Arrays.equals( fanFold1, fanFold ) );
fanFold = stringToKey.setParity( fanFold );
assertTrue( "Key match", Arrays.equals( intermediateKey1, fanFold ) );
byte[] secretKey = getDesKey( paddedByteArray, fanFold );
assertTrue( "Key match", Arrays.equals( desKey1, secretKey ) );
}
/**
* Tests DES StringToKey test vector 2 from RFC 3961 with intermediate step checks.
*
* @throws InvalidKeyException
*/
public void testIntermediateDesStringToKeyVector2() throws InvalidKeyException
{
String passPhrase = "potatoeWHITEHOUSE.GOVdanny";
byte[] encodedByteArray = stringToKey.characterEncodeString( passPhrase );
byte[] paddedByteArray = stringToKey.padString( encodedByteArray );
byte[] fanFold = stringToKey.fanFold( paddedByteArray );
assertTrue( "Key match", Arrays.equals( fanFold2, fanFold ) );
fanFold = stringToKey.setParity( fanFold );
assertTrue( "Key match", Arrays.equals( intermediateKey2, fanFold ) );
byte[] secretKey = getDesKey( paddedByteArray, fanFold );
assertTrue( "Key match", Arrays.equals( desKey2, secretKey ) );
}
/**
* Test harness method for checking intermediate key state, which is not
* exposed from {@link DesStringToKey}.
*
* @param paddedByteArray The input passphrase.
* @param intermediateKey The intermediate key generated by fan-folding and parity-adjustment.
* @return The final DES key.
* @throws InvalidKeyException
*/
private byte[] getDesKey( byte[] paddedByteArray, byte[] intermediateKey ) throws InvalidKeyException
{
if ( DESKeySpec.isWeak( intermediateKey, 0 ) )
{
intermediateKey = stringToKey.getStrongKey( intermediateKey );
}
byte[] secretKey = stringToKey.calculateChecksum( paddedByteArray, intermediateKey );
secretKey = stringToKey.setParity( secretKey );
if ( DESKeySpec.isWeak( secretKey, 0 ) )
{
secretKey = stringToKey.getStrongKey( secretKey );
}
return secretKey;
}
}