/*
 *  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;


import static org.apache.directory.server.integ.ServerIntegrationUtils.getWiredContext;
import static org.junit.Assert.assertEquals;
import static org.junit.Assert.assertFalse;
import static org.junit.Assert.assertTrue;
import static org.junit.Assert.fail;

import java.io.IOException;
import java.net.UnknownHostException;
import java.security.InvalidKeyException;
import java.util.Arrays;
import java.util.HashMap;
import java.util.Hashtable;
import java.util.Map;

import javax.crypto.spec.DESKeySpec;
import javax.naming.Context;
import javax.naming.NamingException;
import javax.naming.directory.Attribute;
import javax.naming.directory.Attributes;
import javax.naming.directory.BasicAttribute;
import javax.naming.directory.BasicAttributes;
import javax.naming.directory.DirContext;
import javax.naming.directory.InitialDirContext;
import javax.naming.directory.ModificationItem;

import org.apache.directory.api.ldap.model.constants.SupportedSaslMechanisms;
import org.apache.directory.api.util.Network;
import org.apache.directory.server.annotations.CreateLdapServer;
import org.apache.directory.server.annotations.CreateTransport;
import org.apache.directory.server.annotations.SaslMechanism;
import org.apache.directory.server.core.annotations.ContextEntry;
import org.apache.directory.server.core.annotations.CreateDS;
import org.apache.directory.server.core.annotations.CreateIndex;
import org.apache.directory.server.core.annotations.CreatePartition;
import org.apache.directory.server.core.integ.AbstractLdapTestUnit;
import org.apache.directory.server.core.integ.FrameworkRunner;
import org.apache.directory.server.core.kerberos.KeyDerivationInterceptor;
import org.apache.directory.server.ldap.handlers.extended.StoredProcedureExtendedOperationHandler;
import org.apache.directory.server.ldap.handlers.sasl.cramMD5.CramMd5MechanismHandler;
import org.apache.directory.server.ldap.handlers.sasl.digestMD5.DigestMd5MechanismHandler;
import org.apache.directory.server.ldap.handlers.sasl.gssapi.GssapiMechanismHandler;
import org.apache.directory.server.ldap.handlers.sasl.ntlm.NtlmMechanismHandler;
import org.apache.directory.server.ldap.handlers.sasl.plain.PlainMechanismHandler;
import org.apache.directory.shared.kerberos.KerberosAttribute;
import org.apache.directory.shared.kerberos.codec.KerberosDecoder;
import org.apache.directory.shared.kerberos.codec.types.EncryptionType;
import org.apache.directory.shared.kerberos.components.EncryptionKey;
import org.apache.directory.shared.kerberos.exceptions.KerberosException;
import org.junit.Before;
import org.junit.Test;
import org.junit.runner.RunWith;


/**
 * An test case for testing the {@link KeyDerivationInterceptor}'s
 * ability to derive Kerberos symmetric keys based on userPassword and principal
 * name and to generate random keys when the special keyword "randomKey" is used.
 *
 * @author <a href="mailto:dev@directory.apache.org">Apache Directory Project</a>
 */
@RunWith(FrameworkRunner.class)
@CreateDS(name = "KeyDerivationServiceIT-class",
    partitions =
        {
            @CreatePartition(
                name = "example",
                suffix = "dc=example,dc=com",
                contextEntry = @ContextEntry(
                    entryLdif =
                    "dn: dc=example,dc=com\n" +
                        "dc: example\n" +
                        "objectClass: top\n" +
                        "objectClass: domain\n\n"),
                indexes =
                    {
                        @CreateIndex(attribute = "objectClass"),
                        @CreateIndex(attribute = "dc"),
                        @CreateIndex(attribute = "ou")
                })
    },
    additionalInterceptors =
        {
            KeyDerivationInterceptor.class
    })
@CreateLdapServer(
    transports =
        {
            @CreateTransport(protocol = "LDAP")
    },
    saslHost = "localhost",
    saslMechanisms =
        {
            @SaslMechanism(name = SupportedSaslMechanisms.PLAIN, implClass = PlainMechanismHandler.class),
            @SaslMechanism(name = SupportedSaslMechanisms.CRAM_MD5, implClass = CramMd5MechanismHandler.class),
            @SaslMechanism(name = SupportedSaslMechanisms.DIGEST_MD5, implClass = DigestMd5MechanismHandler.class),
            @SaslMechanism(name = SupportedSaslMechanisms.GSSAPI, implClass = GssapiMechanismHandler.class),
            @SaslMechanism(name = SupportedSaslMechanisms.NTLM, implClass = NtlmMechanismHandler.class),
            @SaslMechanism(name = SupportedSaslMechanisms.GSS_SPNEGO, implClass = NtlmMechanismHandler.class)
    },
    extendedOpHandlers =
        {
            StoredProcedureExtendedOperationHandler.class
    })
public class KeyDerivationServiceIT extends AbstractLdapTestUnit
{
    private static final String RDN = "uid=hnelson,ou=users,dc=example,dc=com";


    private void checkKeyNumber( Attributes attributes )
    {
        Attribute krb5key = attributes.get( "krb5key" );

        String vendor = System.getProperty( "java.vm.vendor" );

        if ( vendor.equalsIgnoreCase( "IBM Corporation" ) )
        {
            // Will be 2 or 3 on IBM JRE whether AES-256 is enabled or not
            assertTrue( "Number of keys", krb5key.size() > 1 );
        }
        else if ( vendor.equalsIgnoreCase( "Sun Microsystems Inc." ) )
        {
            // Could be 4 or 5 depending on whether AES-256 is enabled or not, on SUN JRE
            assertTrue( "Number of keys", krb5key.size() > 3 );
        }
        else if ( vendor.equalsIgnoreCase( "BEA Systems, Inc." ) )
        {
            // Could be 4 or 5 depending on whether AES-256 is enabled or not, on BEA JRockit
            assertTrue( "Number of keys", krb5key.size() > 3 );
        }
        else if ( vendor.equalsIgnoreCase( "Oracle Corporation" ) )
        {
            // Could be 4 or 5 depending on whether AES-256 is enabled or not, on Oracle JRockit
            assertTrue( "Number of keys", krb5key.size() > 3 );
        }
        else if ( vendor.equalsIgnoreCase( "Apple Inc." ) )
        {
            // Could be 4 or 5 depending on whether AES-256 is enabled or not, on Apple JVM
            assertTrue( "Number of keys", krb5key.size() > 3 );
        }
        else if ( vendor.equalsIgnoreCase( "Apple Inc." ) )
        {
            // Could be 4 or 5 depending on whether AES-256 is enabled or not, on Apple JVM
            assertTrue( "Number of keys", krb5key.size() > 3 );
        }
        else if ( vendor.equalsIgnoreCase( "\"Apple Computer, Inc.\"" ) )
        {
            // Could be 4 or 5 depending on whether AES-256 is enabled or not, on Apple JVM
            assertTrue( "Number of keys", krb5key.size() > 3 );
        }
        else if ( vendor.equalsIgnoreCase( "Azul Systems, Inc." ) )
        {
            assertTrue( "Number of keys", krb5key.size() > 4 );
        }
        else if ( vendor.equalsIgnoreCase( "AdoptOpenJDK" ) )
        {
            assertTrue( "Number of keys", krb5key.size() > 4 );
        }
        else if ( vendor.equalsIgnoreCase( "Eclipse OpenJ9" ) )
        {
            assertTrue( "Number of keys", krb5key.size() > 4 );
        }
        else
        {
            fail( "Unkown JVM/keysize: '" + vendor + "' / " + krb5key.size() );
        }
    }


    /**
     * Set up a partition for EXAMPLE.COM, add the Key Derivation interceptor, enable
     * the krb5kdc schema, and add a user principal to test authentication with.
     */
    @Before
    public void setUp() throws Exception
    {
        DirContext schemaRoot = ( DirContext ) getWiredContext( getLdapServer() ).lookup( "ou=schema" );

        // -------------------------------------------------------------------
        // Enable the krb5kdc schema
        // -------------------------------------------------------------------

        // check if krb5kdc is disabled
        Attributes krb5kdcAttrs = schemaRoot.getAttributes( "cn=Krb5kdc" );
        boolean isKrb5KdcDisabled = false;

        if ( krb5kdcAttrs.get( "m-disabled" ) != null )
        {
            isKrb5KdcDisabled = ( ( String ) krb5kdcAttrs.get( "m-disabled" ).get() ).equalsIgnoreCase( "TRUE" );
        }

        // if krb5kdc is disabled then enable it
        if ( isKrb5KdcDisabled )
        {
            Attribute disabled = new BasicAttribute( "m-disabled" );
            ModificationItem[] mods = new ModificationItem[]
                { new ModificationItem( DirContext.REMOVE_ATTRIBUTE, disabled ) };
            schemaRoot.modifyAttributes( "cn=Krb5kdc", mods );
        }

        DirContext ctx = ( DirContext ) getWiredContext( getLdapServer() ).lookup( "dc=example,dc=com" );
        Attributes attrs = getOrgUnitAttributes( "users" );
        DirContext users = ctx.createSubcontext( "ou=users", attrs );

        attrs = getPersonAttributes( "Nelson", "Horatio Nelson", "hnelson", "secret", "hnelson@EXAMPLE.COM" );
        users.createSubcontext( "uid=hnelson", attrs );
        ctx.close();
    }


    /**
     * Tests that the addition of an entry caused keys to be derived and added.
     *
     * @throws NamingException failure to perform LDAP operations
     * @throws IOException on network errors
     */
    @Test
    public void testAddDerivedKeys() throws NamingException, KerberosException, UnknownHostException
    {
        Hashtable<String, String> env = new Hashtable<String, String>();
        env.put( Context.INITIAL_CONTEXT_FACTORY, "com.sun.jndi.ldap.LdapCtxFactory" );
        env.put( Context.PROVIDER_URL, Network.ldapLoopbackUrl( getLdapServer().getPort() )  );

        env.put( Context.SECURITY_AUTHENTICATION, "simple" );
        env.put( Context.SECURITY_PRINCIPAL, "uid=hnelson,ou=users,dc=example,dc=com" );
        env.put( Context.SECURITY_CREDENTIALS, "secret" );
        env.put( "java.naming.ldap.attributes.binary", "krb5key" );

        DirContext ctx = new InitialDirContext( env );

        String[] attrIDs =
            { "uid", "userPassword", "krb5Key", "krb5KeyVersionNumber" };

        Attributes attributes = ctx.getAttributes( RDN, attrIDs );

        String uid = null;

        if ( attributes.get( "uid" ) != null )
        {
            uid = ( String ) attributes.get( "uid" ).get();
        }

        assertEquals( "hnelson", uid );

        byte[] userPassword = null;

        if ( attributes.get( "userPassword" ) != null )
        {
            userPassword = ( byte[] ) attributes.get( "userPassword" ).get();
        }

        checkKeyNumber( attributes );

        byte[] testPasswordBytes =
            { ( byte ) 0x73, ( byte ) 0x65, ( byte ) 0x63, ( byte ) 0x72, ( byte ) 0x65, ( byte ) 0x74 };
        assertTrue( Arrays.equals( userPassword, testPasswordBytes ) );

        Attribute krb5key = attributes.get( "krb5key" );

        Map<EncryptionType, EncryptionKey> map = reconstituteKeyMap( krb5key );
        EncryptionKey encryptionKey = map.get( EncryptionType.DES_CBC_MD5 );

        byte[] testKeyBytes =
            { ( byte ) 0xF4, ( byte ) 0xA7, ( byte ) 0x13, ( byte ) 0x64, ( byte ) 0x8A, ( byte ) 0x61, ( byte ) 0xCE,
                ( byte ) 0x5B };

        assertTrue( Arrays.equals( encryptionKey.getKeyValue(), testKeyBytes ) );
        assertEquals( EncryptionType.DES_CBC_MD5, encryptionKey.getKeyType() );

        int keyVersionNumber = -1;

        if ( attributes.get( KerberosAttribute.KRB5_KEY_VERSION_NUMBER_AT ) != null )
        {
            keyVersionNumber = Integer.valueOf( ( String ) attributes
                .get( KerberosAttribute.KRB5_KEY_VERSION_NUMBER_AT ).get() );
        }

        assertEquals( "Key version number", 0, keyVersionNumber );
        ctx.close();
    }


    /**
     * Tests that the modification of an entry caused keys to be derived and modified.  The
     * modify request contains both the 'userPassword' and the 'krb5PrincipalName'.
     *
     * @throws NamingException failure to perform LDAP operations
     * @throws IOException on network errors
     */
    @Test
    public void testModifyDerivedKeys() throws NamingException, KerberosException, UnknownHostException
    {
        Hashtable<String, String> env = new Hashtable<String, String>();
        env.put( Context.INITIAL_CONTEXT_FACTORY, "com.sun.jndi.ldap.LdapCtxFactory" );
        env.put( Context.PROVIDER_URL, Network.ldapLoopbackUrl( getLdapServer().getPort() ) );

        env.put( Context.SECURITY_AUTHENTICATION, "simple" );
        env.put( Context.SECURITY_PRINCIPAL, "uid=hnelson,ou=users,dc=example,dc=com" );
        env.put( Context.SECURITY_CREDENTIALS, "secret" );
        env.put( "java.naming.ldap.attributes.binary", "krb5key" );

        DirContext ctx = new InitialDirContext( env );

        String newPrincipalName = "hnelson@EXAMPLE.COM";
        String newUserPassword = "secretsecret";

        // Modify password.
        Attributes attributes = new BasicAttributes( true );
        Attribute attr = new BasicAttribute( "userPassword", newUserPassword );
        attributes.put( attr );
        attr = new BasicAttribute( KerberosAttribute.KRB5_PRINCIPAL_NAME_AT, newPrincipalName );
        attributes.put( attr );

        DirContext person = ( DirContext ) ctx.lookup( RDN );
        person.modifyAttributes( "", DirContext.REPLACE_ATTRIBUTE, attributes );

        // Read again from directory.
        person = ( DirContext ) ctx.lookup( RDN );

        attributes = person.getAttributes( "" );

        byte[] userPassword = null;

        if ( attributes.get( "userPassword" ) != null )
        {
            userPassword = ( byte[] ) attributes.get( "userPassword" ).get();
        }

        checkKeyNumber( attributes );

        byte[] testBytes =
            { 0x73, 0x65, 0x63, 0x72, 0x65, 0x74, 0x73, 0x65, 0x63, 0x72, 0x65, 0x74 };
        assertTrue( Arrays.equals( userPassword, testBytes ) );

        Attribute krb5key = attributes.get( "krb5key" );
        Map<EncryptionType, EncryptionKey> map = reconstituteKeyMap( krb5key );
        EncryptionKey encryptionKey = map.get( EncryptionType.DES_CBC_MD5 );

        byte[] testKeyBytes =
            { ( byte ) 0x16, ( byte ) 0x4A, ( byte ) 0x6D, ( byte ) 0x89, ( byte ) 0x5D, ( byte ) 0x76, ( byte ) 0x0E,
                ( byte ) 0x23 };

        assertTrue( Arrays.equals( encryptionKey.getKeyValue(), testKeyBytes ) );
        assertEquals( EncryptionType.DES_CBC_MD5, encryptionKey.getKeyType() );

        int keyVersionNumber = -1;

        if ( attributes.get( KerberosAttribute.KRB5_KEY_VERSION_NUMBER_AT ) != null )
        {
            keyVersionNumber = Integer.valueOf( ( String ) attributes
                .get( KerberosAttribute.KRB5_KEY_VERSION_NUMBER_AT ).get() );
        }

        assertEquals( "Key version number", 1, keyVersionNumber );

        newUserPassword = "secretsecretsecret";

        // Modify password.
        attributes = new BasicAttributes( true );
        attr = new BasicAttribute( "userPassword", newUserPassword );
        attributes.put( attr );
        attr = new BasicAttribute( KerberosAttribute.KRB5_PRINCIPAL_NAME_AT, newPrincipalName );
        attributes.put( attr );

        person = ( DirContext ) ctx.lookup( RDN );
        person.modifyAttributes( "", DirContext.REPLACE_ATTRIBUTE, attributes );

        // Read again from directory.
        person = ( DirContext ) ctx.lookup( RDN );

        attributes = person.getAttributes( "" );

        if ( attributes.get( "userPassword" ) != null )
        {
            userPassword = ( byte[] ) attributes.get( "userPassword" ).get();
        }

        assertEquals( "password length", 18, userPassword.length );

        if ( attributes.get( KerberosAttribute.KRB5_KEY_VERSION_NUMBER_AT ) != null )
        {
            keyVersionNumber = Integer.valueOf( ( String ) attributes
                .get( KerberosAttribute.KRB5_KEY_VERSION_NUMBER_AT ).get() );
        }

        assertEquals( "Key version number", 2, keyVersionNumber );

        newUserPassword = "secretsecretsecretsecret";

        // Modify password.
        attributes = new BasicAttributes( true );
        attr = new BasicAttribute( "userPassword", newUserPassword );
        attributes.put( attr );
        attr = new BasicAttribute( KerberosAttribute.KRB5_PRINCIPAL_NAME_AT, newPrincipalName );
        attributes.put( attr );

        person = ( DirContext ) ctx.lookup( RDN );
        person.modifyAttributes( "", DirContext.REPLACE_ATTRIBUTE, attributes );

        // Read again from directory.
        person = ( DirContext ) ctx.lookup( RDN );

        attributes = person.getAttributes( "" );

        if ( attributes.get( "userPassword" ) != null )
        {
            userPassword = ( byte[] ) attributes.get( "userPassword" ).get();
        }

        assertEquals( "password length", 24, userPassword.length );

        if ( attributes.get( KerberosAttribute.KRB5_KEY_VERSION_NUMBER_AT ) != null )
        {
            keyVersionNumber = Integer.valueOf( ( String ) attributes
                .get( KerberosAttribute.KRB5_KEY_VERSION_NUMBER_AT ).get() );
        }

        assertEquals( "Key version number", 3, keyVersionNumber );
        ctx.close();
    }


    /**
     * Tests that the modification of an entry caused keys to be derived and modified.  The
     * modify request contains only the 'userPassword'.  The 'krb5PrincipalName' is to be
     * obtained from the initial add of the user principal entry.
     *
     * @throws NamingException failure to perform LDAP operations
     * @throws IOException on network errors
     */
    @Test
    public void testModifyDerivedKeysWithoutPrincipalName() throws NamingException, KerberosException,
        UnknownHostException
    {
        Hashtable<String, String> env = new Hashtable<String, String>();
        env.put( Context.INITIAL_CONTEXT_FACTORY, "com.sun.jndi.ldap.LdapCtxFactory" );
        env.put( Context.PROVIDER_URL, Network.ldapLoopbackUrl( getLdapServer().getPort() ) );

        env.put( Context.SECURITY_AUTHENTICATION, "simple" );
        env.put( Context.SECURITY_PRINCIPAL, "uid=hnelson,ou=users,dc=example,dc=com" );
        env.put( Context.SECURITY_CREDENTIALS, "secret" );
        env.put( "java.naming.ldap.attributes.binary", "krb5key" );

        DirContext ctx = new InitialDirContext( env );

        String newUserPassword = "secretsecret";

        // Modify password.
        Attributes attributes = new BasicAttributes( true );
        Attribute attr = new BasicAttribute( "userPassword", newUserPassword );
        attributes.put( attr );

        DirContext person = ( DirContext ) ctx.lookup( RDN );
        person.modifyAttributes( "", DirContext.REPLACE_ATTRIBUTE, attributes );

        // Read again from directory.
        person = ( DirContext ) ctx.lookup( RDN );

        attributes = person.getAttributes( "" );

        byte[] userPassword = null;

        if ( attributes.get( "userPassword" ) != null )
        {
            userPassword = ( byte[] ) attributes.get( "userPassword" ).get();
        }

        checkKeyNumber( attributes );

        byte[] testBytes =
            { 0x73, 0x65, 0x63, 0x72, 0x65, 0x74, 0x73, 0x65, 0x63, 0x72, 0x65, 0x74 };
        assertTrue( Arrays.equals( userPassword, testBytes ) );

        Attribute krb5key = attributes.get( "krb5key" );
        Map<EncryptionType, EncryptionKey> map = reconstituteKeyMap( krb5key );
        EncryptionKey encryptionKey = map.get( EncryptionType.DES_CBC_MD5 );

        byte[] testKeyBytes =
            { ( byte ) 0x16, ( byte ) 0x4A, ( byte ) 0x6D, ( byte ) 0x89, ( byte ) 0x5D, ( byte ) 0x76, ( byte ) 0x0E,
                ( byte ) 0x23 };

        assertTrue( Arrays.equals( encryptionKey.getKeyValue(), testKeyBytes ) );
        assertEquals( EncryptionType.DES_CBC_MD5, encryptionKey.getKeyType() );

        int keyVersionNumber = -1;

        if ( attributes.get( KerberosAttribute.KRB5_KEY_VERSION_NUMBER_AT ) != null )
        {
            keyVersionNumber = Integer.valueOf( ( String ) attributes
                .get( KerberosAttribute.KRB5_KEY_VERSION_NUMBER_AT ).get() );
        }

        assertEquals( "Key version number", 1, keyVersionNumber );

        newUserPassword = "secretsecretsecret";

        // Modify password.
        attributes = new BasicAttributes( true );
        attr = new BasicAttribute( "userPassword", newUserPassword );
        attributes.put( attr );

        person = ( DirContext ) ctx.lookup( RDN );
        person.modifyAttributes( "", DirContext.REPLACE_ATTRIBUTE, attributes );

        // Read again from directory.
        person = ( DirContext ) ctx.lookup( RDN );

        attributes = person.getAttributes( "" );

        if ( attributes.get( "userPassword" ) != null )
        {
            userPassword = ( byte[] ) attributes.get( "userPassword" ).get();
        }

        assertEquals( "password length", 18, userPassword.length );

        if ( attributes.get( KerberosAttribute.KRB5_KEY_VERSION_NUMBER_AT ) != null )
        {
            keyVersionNumber = Integer.valueOf( ( String ) attributes
                .get( KerberosAttribute.KRB5_KEY_VERSION_NUMBER_AT ).get() );
        }

        assertEquals( "Key version number", 2, keyVersionNumber );

        newUserPassword = "secretsecretsecretsecret";

        // Modify password.
        attributes = new BasicAttributes( true );
        attr = new BasicAttribute( "userPassword", newUserPassword );
        attributes.put( attr );

        person = ( DirContext ) ctx.lookup( RDN );
        person.modifyAttributes( "", DirContext.REPLACE_ATTRIBUTE, attributes );

        // Read again from directory.
        person = ( DirContext ) ctx.lookup( RDN );

        attributes = person.getAttributes( "" );

        if ( attributes.get( "userPassword" ) != null )
        {
            userPassword = ( byte[] ) attributes.get( "userPassword" ).get();
        }

        assertEquals( "password length", 24, userPassword.length );

        if ( attributes.get( KerberosAttribute.KRB5_KEY_VERSION_NUMBER_AT ) != null )
        {
            keyVersionNumber = Integer.valueOf( ( String ) attributes
                .get( KerberosAttribute.KRB5_KEY_VERSION_NUMBER_AT ).get() );
        }

        assertEquals( "Key version number", 3, keyVersionNumber );
        ctx.close();
    }


    /**
     * Tests that the addition of an entry caused random keys to be derived and added.
     *
     * @throws NamingException failure to perform LDAP operations
     * @throws IOException on network errors
     * @throws InvalidKeyException if the incorrect key results
     */
    @Test
    public void testAddRandomKeys() throws NamingException, KerberosException, InvalidKeyException,
        UnknownHostException
    {
        Hashtable<String, String> env = new Hashtable<String, String>();
        env.put( "java.naming.factory.initial", "com.sun.jndi.ldap.LdapCtxFactory" );
        env.put( "java.naming.provider.url",
            Network.ldapLoopbackUrl( getLdapServer().getPort() ) + "/ou=users,dc=example,dc=com" );
        env.put( "java.naming.security.principal", "uid=admin,ou=system" );
        env.put( "java.naming.security.credentials", "secret" );
        env.put( "java.naming.security.authentication", "simple" );
        env.put( "java.naming.ldap.attributes.binary", "krb5key" );
        DirContext ctx = new InitialDirContext( env );

        Attributes attrs = getPersonAttributes( "Quist", "Thomas Quist", "tquist", "randomKey", "tquist@EXAMPLE.COM" );
        ctx.createSubcontext( "uid=tquist", attrs );

        attrs = getPersonAttributes( "Fryer", "John Fryer", "jfryer", "randomKey", "jfryer@EXAMPLE.COM" );
        ctx.createSubcontext( "uid=jfryer", attrs );

        String[] attrIDs =
            { "uid", "userPassword", "krb5Key" };

        Attributes tquistAttrs = ctx.getAttributes( "uid=tquist", attrIDs );
        Attributes jfryerAttrs = ctx.getAttributes( "uid=jfryer", attrIDs );

        String uid = null;
        byte[] userPassword = null;

        if ( tquistAttrs.get( "uid" ) != null )
        {
            uid = ( String ) tquistAttrs.get( "uid" ).get();
        }

        assertEquals( "tquist", uid );

        if ( tquistAttrs.get( "userPassword" ) != null )
        {
            userPassword = ( byte[] ) tquistAttrs.get( "userPassword" ).get();
        }

        // Bytes for "randomKey."
        byte[] testPasswordBytes =
            { ( byte ) 0x72, ( byte ) 0x61, ( byte ) 0x6E, ( byte ) 0x64, ( byte ) 0x6F, ( byte ) 0x6D, ( byte ) 0x4B,
                ( byte ) 0x65, ( byte ) 0x79 };
        assertTrue( Arrays.equals( testPasswordBytes, userPassword ) );

        if ( jfryerAttrs.get( "uid" ) != null )
        {
            uid = ( String ) jfryerAttrs.get( "uid" ).get();
        }

        assertEquals( "jfryer", uid );

        if ( jfryerAttrs.get( "userPassword" ) != null )
        {
            userPassword = ( byte[] ) jfryerAttrs.get( "userPassword" ).get();
        }

        assertTrue( Arrays.equals( testPasswordBytes, userPassword ) );

        byte[] testKeyBytes =
            { ( byte ) 0xF4, ( byte ) 0xA7, ( byte ) 0x13, ( byte ) 0x64, ( byte ) 0x8A, ( byte ) 0x61, ( byte ) 0xCE,
                ( byte ) 0x5B };

        Attribute krb5key = tquistAttrs.get( "krb5key" );
        Map<EncryptionType, EncryptionKey> map = reconstituteKeyMap( krb5key );
        EncryptionKey encryptionKey = map.get( EncryptionType.DES_CBC_MD5 );
        byte[] tquistKey = encryptionKey.getKeyValue();

        assertEquals( EncryptionType.DES_CBC_MD5, encryptionKey.getKeyType() );

        krb5key = jfryerAttrs.get( "krb5key" );
        map = reconstituteKeyMap( krb5key );
        encryptionKey = map.get( EncryptionType.DES_CBC_MD5 );
        byte[] jfryerKey = encryptionKey.getKeyValue();

        assertEquals( EncryptionType.DES_CBC_MD5, encryptionKey.getKeyType() );

        assertEquals( "Key length", 8, tquistKey.length );
        assertEquals( "Key length", 8, jfryerKey.length );

        assertFalse( Arrays.equals( testKeyBytes, tquistKey ) );
        assertFalse( Arrays.equals( testKeyBytes, jfryerKey ) );
        assertFalse( Arrays.equals( jfryerKey, tquistKey ) );

        byte[] tquistDerivedKey =
            { ( byte ) 0xFD, ( byte ) 0x7F, ( byte ) 0x6B, ( byte ) 0x83, ( byte ) 0xA4, ( byte ) 0x76, ( byte ) 0xC1,
                ( byte ) 0xEA };
        byte[] jfryerDerivedKey =
            { ( byte ) 0xA4, ( byte ) 0x10, ( byte ) 0x3B, ( byte ) 0x49, ( byte ) 0xCE, ( byte ) 0x0B, ( byte ) 0xB5,
                ( byte ) 0x07 };

        assertFalse( Arrays.equals( tquistDerivedKey, tquistKey ) );
        assertFalse( Arrays.equals( jfryerDerivedKey, jfryerKey ) );

        assertTrue( DESKeySpec.isParityAdjusted( tquistKey, 0 ) );
        assertTrue( DESKeySpec.isParityAdjusted( jfryerKey, 0 ) );
        ctx.close();
    }


    /**
     * Convenience method for creating a person.
     *
     * @param cn the commonName of the person
     * @param sn the surName of the person
     * @param uid the unique id of the person
     * @param userPassword the password of the person
     * @param principal the kerberos principal name for the person
     * @return the attributes of the person entry
     */
    protected Attributes getPersonAttributes( String sn, String cn, String uid, String userPassword, String principal )
    {
        Attributes attrs = new BasicAttributes( true );
        Attribute ocls = new BasicAttribute( "objectClass" );
        ocls.add( "top" );
        ocls.add( "person" ); // sn $ cn
        ocls.add( "inetOrgPerson" ); // uid
        ocls.add( "krb5principal" );
        ocls.add( "krb5kdcentry" );
        attrs.put( ocls );
        attrs.put( "cn", cn );
        attrs.put( "sn", sn );
        attrs.put( "uid", uid );
        attrs.put( "userPassword", userPassword );
        attrs.put( KerberosAttribute.KRB5_PRINCIPAL_NAME_AT, principal );
        attrs.put( KerberosAttribute.KRB5_KEY_VERSION_NUMBER_AT, "0" );

        return attrs;
    }


    /**
     * Convenience method for creating an organizational unit.
     *
     * @param ou the organizational unit to create
     * @return the attributes of the organizationalUnit
     */
    protected Attributes getOrgUnitAttributes( String ou )
    {
        Attributes attrs = new BasicAttributes( true );
        Attribute ocls = new BasicAttribute( "objectClass" );
        ocls.add( "top" );
        ocls.add( "organizationalUnit" );
        attrs.put( ocls );
        attrs.put( "ou", ou );

        return attrs;
    }


    private Map<EncryptionType, EncryptionKey> reconstituteKeyMap( Attribute krb5key ) throws NamingException,
        KerberosException
    {
        Map<EncryptionType, EncryptionKey> map = new HashMap<EncryptionType, EncryptionKey>();

        for ( int ii = 0; ii < krb5key.size(); ii++ )
        {
            byte[] encryptionKeyBytes = ( byte[] ) krb5key.get( ii );
            EncryptionKey encryptionKey = KerberosDecoder.decodeEncryptionKey( encryptionKeyBytes );
            map.put( encryptionKey.getKeyType(), encryptionKey );
        }

        return map;
    }
}
