You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@directory.apache.org by er...@apache.org on 2007/05/04 06:47:24 UTC

svn commit: r535091 - in /directory/apacheds/branches/kerberos-encryption-types/kerberos-shared/src: main/java/org/apache/directory/server/kerberos/shared/crypto/encryption/ test/java/org/apache/directory/server/kerberos/shared/crypto/encryption/

Author: erodriguez
Date: Thu May  3 21:47:23 2007
New Revision: 535091

URL: http://svn.apache.org/viewvc?view=rev&rev=535091
Log:
Changes to random-to-key and string-to-key factories:
o  Improved and homogenized API's.
o  Collateral refactoring due to API changes.
o  Added unit tests to cover random-to-key factory.

Modified:
    directory/apacheds/branches/kerberos-encryption-types/kerberos-shared/src/main/java/org/apache/directory/server/kerberos/shared/crypto/encryption/KerberosKeyFactory.java
    directory/apacheds/branches/kerberos-encryption-types/kerberos-shared/src/main/java/org/apache/directory/server/kerberos/shared/crypto/encryption/RandomKeyFactory.java
    directory/apacheds/branches/kerberos-encryption-types/kerberos-shared/src/test/java/org/apache/directory/server/kerberos/shared/crypto/encryption/KerberosKeyFactoryTest.java
    directory/apacheds/branches/kerberos-encryption-types/kerberos-shared/src/test/java/org/apache/directory/server/kerberos/shared/crypto/encryption/RandomKeyFactoryTest.java

Modified: directory/apacheds/branches/kerberos-encryption-types/kerberos-shared/src/main/java/org/apache/directory/server/kerberos/shared/crypto/encryption/KerberosKeyFactory.java
URL: http://svn.apache.org/viewvc/directory/apacheds/branches/kerberos-encryption-types/kerberos-shared/src/main/java/org/apache/directory/server/kerberos/shared/crypto/encryption/KerberosKeyFactory.java?view=diff&rev=535091&r1=535090&r2=535091
==============================================================================
--- directory/apacheds/branches/kerberos-encryption-types/kerberos-shared/src/main/java/org/apache/directory/server/kerberos/shared/crypto/encryption/KerberosKeyFactory.java (original)
+++ directory/apacheds/branches/kerberos-encryption-types/kerberos-shared/src/main/java/org/apache/directory/server/kerberos/shared/crypto/encryption/KerberosKeyFactory.java Thu May  3 21:47:23 2007
@@ -21,14 +21,17 @@
 package org.apache.directory.server.kerberos.shared.crypto.encryption;
 
 
-import java.util.ArrayList;
 import java.util.Collections;
+import java.util.HashMap;
 import java.util.Iterator;
-import java.util.List;
+import java.util.Map;
+import java.util.Set;
 
 import javax.security.auth.kerberos.KerberosKey;
 import javax.security.auth.kerberos.KerberosPrincipal;
 
+import org.apache.directory.server.kerberos.shared.messages.value.EncryptionKey;
+
 
 /**
  * A factory class for producing {@link KerberosKey}'s.  For a list of desired cipher
@@ -40,34 +43,34 @@
  */
 public class KerberosKeyFactory
 {
-    /** A list of the default cipher types to derive keys for. */
-    private static final List<String> DEFAULT_CIPHERS;
+    /** A map of default encryption types mapped to cipher names. */
+    private static final Map<EncryptionType, String> DEFAULT_CIPHERS;
 
     static
     {
-        List<String> list = new ArrayList<String>();
+        Map<EncryptionType, String> map = new HashMap<EncryptionType, String>();
 
-        list.add( "DES" );
-        list.add( "DESede" );
-        list.add( "ArcFourHmac" );
-        list.add( "AES128" );
-        list.add( "AES256" );
+        map.put( EncryptionType.DES_CBC_MD5, "DES" );
+        map.put( EncryptionType.DES3_CBC_SHA1_KD, "DESede" );
+        map.put( EncryptionType.RC4_HMAC, "ArcFourHmac" );
+        map.put( EncryptionType.AES128_CTS_HMAC_SHA1_96, "AES128" );
+        map.put( EncryptionType.AES256_CTS_HMAC_SHA1_96, "AES256" );
 
-        DEFAULT_CIPHERS = Collections.unmodifiableList( list );
+        DEFAULT_CIPHERS = Collections.unmodifiableMap( map );
     }
 
 
     /**
-     * Get a list of KerberosKey's for a given principal name and passphrase.  The default set
-     * of cipher types is used.
-     *
+     * Get a map of KerberosKey's for a given principal name and passphrase.  The default set
+     * of encryption types is used.
+     * 
      * @param principalName The principal name to use for key derivation.
      * @param passPhrase The passphrase to use for key derivation.
-     * @return The list of KerberosKey's.
+     * @return The map of KerberosKey's.
      */
-    public static List<KerberosKey> getKerberosKeys( String principalName, String passPhrase )
+    public static Map<EncryptionType, EncryptionKey> getKerberosKeys( String principalName, String passPhrase )
     {
-        return getKerberosKeys( principalName, passPhrase, DEFAULT_CIPHERS );
+        return getKerberosKeys( principalName, passPhrase, DEFAULT_CIPHERS.keySet() );
     }
 
 
@@ -77,18 +80,26 @@
      *
      * @param principalName The principal name to use for key derivation.
      * @param passPhrase The passphrase to use for key derivation.
-     * @param ciphers The list of ciphers to derive keys for.
+     * @param ciphers The set of ciphers to derive keys for.
      * @return The list of KerberosKey's.
      */
-    public static List<KerberosKey> getKerberosKeys( String principalName, String passPhrase, List<String> ciphers )
+    public static Map<EncryptionType, EncryptionKey> getKerberosKeys( String principalName, String passPhrase,
+        Set<EncryptionType> ciphers )
     {
         KerberosPrincipal principal = new KerberosPrincipal( principalName );
-        List<KerberosKey> kerberosKeys = new ArrayList<KerberosKey>();
+        Map<EncryptionType, EncryptionKey> kerberosKeys = new HashMap<EncryptionType, EncryptionKey>();
 
-        Iterator<String> it = ciphers.iterator();
+        Iterator<EncryptionType> it = ciphers.iterator();
         while ( it.hasNext() )
         {
-            kerberosKeys.add( new KerberosKey( principal, passPhrase.toCharArray(), it.next() ) );
+            EncryptionType encryptionType = it.next();
+            String algorithm = DEFAULT_CIPHERS.get( encryptionType );
+
+            KerberosKey kerberosKey = new KerberosKey( principal, passPhrase.toCharArray(), algorithm );
+            EncryptionKey encryptionKey = new EncryptionKey( encryptionType, kerberosKey.getEncoded(), kerberosKey
+                .getVersionNumber() );
+
+            kerberosKeys.put( encryptionType, encryptionKey );
         }
 
         return kerberosKeys;

Modified: directory/apacheds/branches/kerberos-encryption-types/kerberos-shared/src/main/java/org/apache/directory/server/kerberos/shared/crypto/encryption/RandomKeyFactory.java
URL: http://svn.apache.org/viewvc/directory/apacheds/branches/kerberos-encryption-types/kerberos-shared/src/main/java/org/apache/directory/server/kerberos/shared/crypto/encryption/RandomKeyFactory.java?view=diff&rev=535091&r1=535090&r2=535091
==============================================================================
--- directory/apacheds/branches/kerberos-encryption-types/kerberos-shared/src/main/java/org/apache/directory/server/kerberos/shared/crypto/encryption/RandomKeyFactory.java (original)
+++ directory/apacheds/branches/kerberos-encryption-types/kerberos-shared/src/main/java/org/apache/directory/server/kerberos/shared/crypto/encryption/RandomKeyFactory.java Thu May  3 21:47:23 2007
@@ -23,7 +23,9 @@
 import java.security.NoSuchAlgorithmException;
 import java.util.Collections;
 import java.util.HashMap;
+import java.util.Iterator;
 import java.util.Map;
+import java.util.Set;
 
 import javax.crypto.KeyGenerator;
 import javax.crypto.SecretKey;
@@ -34,14 +36,16 @@
 
 
 /**
- * Generates new random keys, suitable for use as session keys.
+ * A factory class for producing random keys, suitable for use as session keys.  For a
+ * list of desired cipher types, Kerberos random-to-key functions are used to derive
+ * keys for DES-, DES3-, AES-, and RC4-based encryption types.
  *
  * @author <a href="mailto:dev@directory.apache.org">Apache Directory Project</a>
  * @version $Rev$, $Date$
  */
 public class RandomKeyFactory
 {
-    /** a map of the default encryption types to the encryption engine class names */
+    /** A map of default encryption types mapped to cipher names. */
     private static final Map<EncryptionType, String> DEFAULT_CIPHERS;
 
     static
@@ -59,11 +63,45 @@
 
 
     /**
-     * Get a new random session key for a given {@link EncryptionType}.
+     * Get a map of random keys.  The default set of encryption types is used.
+     * 
+     * @return The map of random keys.
+     * @throws KerberosException 
+     */
+    public static Map<EncryptionType, EncryptionKey> getRandomKeys() throws KerberosException
+    {
+        return getRandomKeys( DEFAULT_CIPHERS.keySet() );
+    }
+
+
+    /**
+     * Get a map of random keys for a list of cipher types to derive keys for.
+     *
+     * @param ciphers The list of ciphers to derive keys for.
+     * @return The list of KerberosKey's.
+     * @throws KerberosException 
+     */
+    public static Map<EncryptionType, EncryptionKey> getRandomKeys( Set<EncryptionType> ciphers ) throws KerberosException
+    {
+        Map<EncryptionType, EncryptionKey> map = new HashMap<EncryptionType, EncryptionKey>();
+
+        Iterator<EncryptionType> it = ciphers.iterator();
+        while ( it.hasNext() )
+        {
+            EncryptionType type = it.next();
+            map.put( type, getRandomKey( type ) );
+        }
+
+        return map;
+    }
+
+
+    /**
+     * Get a new random key for a given {@link EncryptionType}.
      * 
      * @param encryptionType 
      * 
-     * @return The new random session key.
+     * @return The new random key.
      * @throws KerberosException 
      */
     public static EncryptionKey getRandomKey( EncryptionType encryptionType ) throws KerberosException

Modified: directory/apacheds/branches/kerberos-encryption-types/kerberos-shared/src/test/java/org/apache/directory/server/kerberos/shared/crypto/encryption/KerberosKeyFactoryTest.java
URL: http://svn.apache.org/viewvc/directory/apacheds/branches/kerberos-encryption-types/kerberos-shared/src/test/java/org/apache/directory/server/kerberos/shared/crypto/encryption/KerberosKeyFactoryTest.java?view=diff&rev=535091&r1=535090&r2=535091
==============================================================================
--- directory/apacheds/branches/kerberos-encryption-types/kerberos-shared/src/test/java/org/apache/directory/server/kerberos/shared/crypto/encryption/KerberosKeyFactoryTest.java (original)
+++ directory/apacheds/branches/kerberos-encryption-types/kerberos-shared/src/test/java/org/apache/directory/server/kerberos/shared/crypto/encryption/KerberosKeyFactoryTest.java Thu May  3 21:47:23 2007
@@ -20,18 +20,18 @@
 package org.apache.directory.server.kerberos.shared.crypto.encryption;
 
 
-import java.util.ArrayList;
 import java.util.Arrays;
-import java.util.HashMap;
-import java.util.Iterator;
-import java.util.List;
+import java.util.HashSet;
 import java.util.Map;
+import java.util.Set;
 
 import javax.security.auth.kerberos.KerberosKey;
 import javax.security.auth.kerberos.KerberosPrincipal;
 
 import junit.framework.TestCase;
 
+import org.apache.directory.server.kerberos.shared.messages.value.EncryptionKey;
+
 
 /**
  * Test cases for string-to-key functions for DES-, DES3-, AES-, and RC4-based
@@ -112,24 +112,22 @@
 
 
     /**
-     * Tests that key derivation can be performed by the factory for a list of cipher types.
+     * Tests that key derivation can be performed by the factory for multiple cipher types.
      */
     public void testKerberosKeyFactory()
     {
         String principalName = "hnelson@EXAMPLE.COM";
         String passPhrase = "secret";
 
-        List<KerberosKey> kerberosKeys = KerberosKeyFactory.getKerberosKeys( principalName, passPhrase );
-
-        Map<EncryptionType, KerberosKey> map = getMapForList( kerberosKeys );
+        Map<EncryptionType, EncryptionKey> map = KerberosKeyFactory.getKerberosKeys( principalName, passPhrase );
 
-        KerberosKey kerberosKey = map.get( EncryptionType.DES_CBC_MD5 );
+        EncryptionKey kerberosKey = map.get( EncryptionType.DES_CBC_MD5 );
 
-        int keyType = kerberosKey.getKeyType();
-        int keyLength = kerberosKey.getEncoded().length;
-        byte[] keyBytes = kerberosKey.getEncoded();
+        EncryptionType keyType = kerberosKey.getKeyType();
+        int keyLength = kerberosKey.getKeyValue().length;
+        byte[] keyBytes = kerberosKey.getKeyValue();
 
-        assertEquals( keyType, 3 );
+        assertEquals( keyType, EncryptionType.DES_CBC_MD5 );
         assertEquals( keyLength, 8 );
         byte[] expectedBytes = new byte[]
             { ( byte ) 0xF4, ( byte ) 0xA7, ( byte ) 0x13, ( byte ) 0x64, ( byte ) 0x8A, ( byte ) 0x61, ( byte ) 0xCE,
@@ -138,10 +136,10 @@
 
         kerberosKey = map.get( EncryptionType.DES3_CBC_SHA1_KD );
         keyType = kerberosKey.getKeyType();
-        keyLength = kerberosKey.getEncoded().length;
-        keyBytes = kerberosKey.getEncoded();
+        keyLength = kerberosKey.getKeyValue().length;
+        keyBytes = kerberosKey.getKeyValue();
 
-        assertEquals( keyType, 16 );
+        assertEquals( keyType, EncryptionType.DES3_CBC_SHA1_KD );
         assertEquals( keyLength, 24 );
         expectedBytes = new byte[]
             { ( byte ) 0x57, ( byte ) 0x07, ( byte ) 0xCE, ( byte ) 0x29, ( byte ) 0x52, ( byte ) 0x92, ( byte ) 0x2C,
@@ -152,10 +150,10 @@
 
         kerberosKey = map.get( EncryptionType.RC4_HMAC );
         keyType = kerberosKey.getKeyType();
-        keyLength = kerberosKey.getEncoded().length;
-        keyBytes = kerberosKey.getEncoded();
+        keyLength = kerberosKey.getKeyValue().length;
+        keyBytes = kerberosKey.getKeyValue();
 
-        assertEquals( keyType, 23 );
+        assertEquals( keyType, EncryptionType.RC4_HMAC );
         assertEquals( keyLength, 16 );
         expectedBytes = new byte[]
             { ( byte ) 0x87, ( byte ) 0x8D, ( byte ) 0x80, ( byte ) 0x14, ( byte ) 0x60, ( byte ) 0x6C, ( byte ) 0xDA,
@@ -165,10 +163,10 @@
 
         kerberosKey = map.get( EncryptionType.AES128_CTS_HMAC_SHA1_96 );
         keyType = kerberosKey.getKeyType();
-        keyLength = kerberosKey.getEncoded().length;
-        keyBytes = kerberosKey.getEncoded();
+        keyLength = kerberosKey.getKeyValue().length;
+        keyBytes = kerberosKey.getKeyValue();
 
-        assertEquals( keyType, 17 );
+        assertEquals( keyType, EncryptionType.AES128_CTS_HMAC_SHA1_96 );
         assertEquals( keyLength, 16 );
         expectedBytes = new byte[]
             { ( byte ) 0xAD, ( byte ) 0x21, ( byte ) 0x4B, ( byte ) 0x38, ( byte ) 0xB6, ( byte ) 0x9D, ( byte ) 0xFC,
@@ -178,10 +176,10 @@
 
         // kerberosKey = map.get( EncryptionType.AES256_CTS_HMAC_SHA1_96 );
         // keyType = kerberosKey.getKeyType();
-        // keyLength = kerberosKey.getEncoded().length;
-        // keyBytes = kerberosKey.getEncoded();
+        // keyLength = kerberosKey.getKeyValue().length;
+        // keyBytes = kerberosKey.getKeyValue();
         //
-        // assertEquals( keyType, 18 );
+        // assertEquals( keyType, EncryptionType.AES256_CTS_HMAC_SHA1_96 );
         // assertEquals( keyLength, 32 );
         // expectedBytes = new byte[]
         //     { ( byte ) 0x3D, ( byte ) 0x33, ( byte ) 0x31, ( byte ) 0x8F, ( byte ) 0xBE, ( byte ) 0x47, ( byte ) 0xE5,
@@ -201,42 +199,25 @@
         String principalName = "hnelson@EXAMPLE.COM";
         String passPhrase = "secret";
 
-        List<String> ciphers = new ArrayList<String>();
-        ciphers.add( "DES" );
-
-        List<KerberosKey> kerberosKeys = KerberosKeyFactory.getKerberosKeys( principalName, passPhrase, ciphers );
+        Set<EncryptionType> encryptionTypes = new HashSet<EncryptionType>();
+        encryptionTypes.add( EncryptionType.DES_CBC_MD5 );
 
-        assertEquals( "List length", 1, kerberosKeys.size() );
+        Map<EncryptionType, EncryptionKey> map = KerberosKeyFactory.getKerberosKeys( principalName, passPhrase,
+            encryptionTypes );
 
-        Map<EncryptionType, KerberosKey> map = getMapForList( kerberosKeys );
+        assertEquals( "List length", 1, map.values().size() );
 
-        KerberosKey kerberosKey = map.get( EncryptionType.DES_CBC_MD5 );
+        EncryptionKey kerberosKey = map.get( EncryptionType.DES_CBC_MD5 );
 
-        int keyType = kerberosKey.getKeyType();
-        int keyLength = kerberosKey.getEncoded().length;
-        byte[] keyBytes = kerberosKey.getEncoded();
+        EncryptionType keyType = kerberosKey.getKeyType();
+        int keyLength = kerberosKey.getKeyValue().length;
+        byte[] keyBytes = kerberosKey.getKeyValue();
 
-        assertEquals( keyType, 3 );
+        assertEquals( keyType, EncryptionType.DES_CBC_MD5 );
         assertEquals( keyLength, 8 );
         byte[] expectedBytes = new byte[]
             { ( byte ) 0xF4, ( byte ) 0xA7, ( byte ) 0x13, ( byte ) 0x64, ( byte ) 0x8A, ( byte ) 0x61, ( byte ) 0xCE,
                 ( byte ) 0x5B };
         assertTrue( Arrays.equals( expectedBytes, keyBytes ) );
-    }
-
-
-    private Map<EncryptionType, KerberosKey> getMapForList( List<KerberosKey> kerberosKeys )
-    {
-        Map<EncryptionType, KerberosKey> map = new HashMap<EncryptionType, KerberosKey>();
-
-        Iterator<KerberosKey> it = kerberosKeys.iterator();
-        while ( it.hasNext() )
-        {
-            KerberosKey kerberosKey = it.next();
-            EncryptionType type = EncryptionType.getTypeByOrdinal( kerberosKey.getKeyType() );
-            map.put( type, kerberosKey );
-        }
-
-        return map;
     }
 }

Modified: directory/apacheds/branches/kerberos-encryption-types/kerberos-shared/src/test/java/org/apache/directory/server/kerberos/shared/crypto/encryption/RandomKeyFactoryTest.java
URL: http://svn.apache.org/viewvc/directory/apacheds/branches/kerberos-encryption-types/kerberos-shared/src/test/java/org/apache/directory/server/kerberos/shared/crypto/encryption/RandomKeyFactoryTest.java?view=diff&rev=535091&r1=535090&r2=535091
==============================================================================
--- directory/apacheds/branches/kerberos-encryption-types/kerberos-shared/src/test/java/org/apache/directory/server/kerberos/shared/crypto/encryption/RandomKeyFactoryTest.java (original)
+++ directory/apacheds/branches/kerberos-encryption-types/kerberos-shared/src/test/java/org/apache/directory/server/kerberos/shared/crypto/encryption/RandomKeyFactoryTest.java Thu May  3 21:47:23 2007
@@ -20,12 +20,18 @@
 package org.apache.directory.server.kerberos.shared.crypto.encryption;
 
 
+import java.util.HashSet;
+import java.util.Map;
+import java.util.Set;
+
 import javax.crypto.KeyGenerator;
 import javax.crypto.SecretKey;
 import javax.crypto.spec.DESKeySpec;
 
 import junit.framework.TestCase;
 
+import org.apache.directory.server.kerberos.shared.messages.value.EncryptionKey;
+
 
 /**
  * Test cases for random-to-key functions for DES-, DES3-, AES-, and RC4-based
@@ -114,5 +120,76 @@
         KeyGenerator keygen = KeyGenerator.getInstance( "RC4" );
         SecretKey key = keygen.generateKey();
         assertEquals( "RC4 key size", 16, key.getEncoded().length );
+    }
+
+
+    /**
+     * Tests that random key generation can be performed by the factory for multiple cipher types.
+     * 
+     * @throws Exception
+     */
+    public void testRandomKeyFactory() throws Exception
+    {
+        Map<EncryptionType, EncryptionKey> map = RandomKeyFactory.getRandomKeys();
+
+        EncryptionKey kerberosKey = map.get( EncryptionType.DES_CBC_MD5 );
+
+        EncryptionType keyType = kerberosKey.getKeyType();
+        int keyLength = kerberosKey.getKeyValue().length;
+
+        assertEquals( keyType, EncryptionType.DES_CBC_MD5 );
+        assertEquals( keyLength, 8 );
+
+        kerberosKey = map.get( EncryptionType.DES3_CBC_SHA1_KD );
+        keyType = kerberosKey.getKeyType();
+        keyLength = kerberosKey.getKeyValue().length;
+
+        assertEquals( keyType, EncryptionType.DES3_CBC_SHA1_KD );
+        assertEquals( keyLength, 24 );
+
+        kerberosKey = map.get( EncryptionType.RC4_HMAC );
+        keyType = kerberosKey.getKeyType();
+        keyLength = kerberosKey.getKeyValue().length;
+
+        assertEquals( keyType, EncryptionType.RC4_HMAC );
+        assertEquals( keyLength, 16 );
+
+        kerberosKey = map.get( EncryptionType.AES128_CTS_HMAC_SHA1_96 );
+        keyType = kerberosKey.getKeyType();
+        keyLength = kerberosKey.getKeyValue().length;
+
+        assertEquals( keyType, EncryptionType.AES128_CTS_HMAC_SHA1_96 );
+        assertEquals( keyLength, 16 );
+
+        // kerberosKey = map.get( EncryptionType.AES256_CTS_HMAC_SHA1_96 );
+        // keyType = kerberosKey.getKeyType();
+        // keyLength = kerberosKey.getKeyValue().length;
+
+        // assertEquals( keyType, EncryptionType.AES256_CTS_HMAC_SHA1_96 );
+        // assertEquals( keyLength, 32 );
+    }
+
+
+    /**
+     * Tests that random key generation can be performed by the factory for a specified cipher type.
+     * 
+     * @throws Exception
+     */
+    public void testRandomKeyFactoryOnlyDes() throws Exception
+    {
+        Set<EncryptionType> encryptionTypes = new HashSet<EncryptionType>();
+        encryptionTypes.add( EncryptionType.DES_CBC_MD5 );
+
+        Map<EncryptionType, EncryptionKey> map = RandomKeyFactory.getRandomKeys( encryptionTypes );
+
+        assertEquals( "List length", 1, map.values().size() );
+
+        EncryptionKey kerberosKey = map.get( EncryptionType.DES_CBC_MD5 );
+
+        EncryptionType keyType = kerberosKey.getKeyType();
+        int keyLength = kerberosKey.getKeyValue().length;
+
+        assertEquals( keyType, EncryptionType.DES_CBC_MD5 );
+        assertEquals( keyLength, 8 );
     }
 }