001    /*
002     *  Licensed to the Apache Software Foundation (ASF) under one
003     *  or more contributor license agreements.  See the NOTICE file
004     *  distributed with this work for additional information
005     *  regarding copyright ownership.  The ASF licenses this file
006     *  to you under the Apache License, Version 2.0 (the
007     *  "License"); you may not use this file except in compliance
008     *  with the License.  You may obtain a copy of the License at
009     *  
010     *    http://www.apache.org/licenses/LICENSE-2.0
011     *  
012     *  Unless required by applicable law or agreed to in writing,
013     *  software distributed under the License is distributed on an
014     *  "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
015     *  KIND, either express or implied.  See the License for the
016     *  specific language governing permissions and limitations
017     *  under the License. 
018     *  
019     */
020    
021    package org.apache.directory.server.kerberos.shared.crypto.encryption;
022    
023    
024    import java.util.Collections;
025    import java.util.HashMap;
026    import java.util.Iterator;
027    import java.util.Map;
028    import java.util.Set;
029    
030    import javax.security.auth.kerberos.KerberosKey;
031    import javax.security.auth.kerberos.KerberosPrincipal;
032    
033    import org.apache.directory.server.kerberos.shared.messages.value.EncryptionKey;
034    
035    
036    /**
037     * A factory class for producing {@link KerberosKey}'s.  For a list of desired cipher
038     * types, Kerberos string-to-key functions are used to derive keys for DES-, DES3-, AES-,
039     * and RC4-based encryption types.
040     *
041     * @author <a href="mailto:dev@directory.apache.org">Apache Directory Project</a>
042     * @version $Rev$, $Date$
043     */
044    public class KerberosKeyFactory
045    {
046        /** A map of default encryption types mapped to cipher names. */
047        private static final Map<EncryptionType, String> DEFAULT_CIPHERS;
048    
049        static
050        {
051            Map<EncryptionType, String> map = new HashMap<EncryptionType, String>();
052    
053            map.put( EncryptionType.DES_CBC_MD5, "DES" );
054            map.put( EncryptionType.DES3_CBC_SHA1_KD, "DESede" );
055            map.put( EncryptionType.RC4_HMAC, "ArcFourHmac" );
056            map.put( EncryptionType.AES128_CTS_HMAC_SHA1_96, "AES128" );
057            map.put( EncryptionType.AES256_CTS_HMAC_SHA1_96, "AES256" );
058    
059            DEFAULT_CIPHERS = Collections.unmodifiableMap( map );
060        }
061    
062    
063        /**
064         * Get a map of KerberosKey's for a given principal name and passphrase.  The default set
065         * of encryption types is used.
066         * 
067         * @param principalName The principal name to use for key derivation.
068         * @param passPhrase The passphrase to use for key derivation.
069         * @return The map of KerberosKey's.
070         */
071        public static Map<EncryptionType, EncryptionKey> getKerberosKeys( String principalName, String passPhrase )
072        {
073            return getKerberosKeys( principalName, passPhrase, DEFAULT_CIPHERS.keySet() );
074        }
075    
076    
077        /**
078         * Get a list of KerberosKey's for a given principal name and passphrase and list of cipher
079         * types to derive keys for.
080         *
081         * @param principalName The principal name to use for key derivation.
082         * @param passPhrase The passphrase to use for key derivation.
083         * @param ciphers The set of ciphers to derive keys for.
084         * @return The list of KerberosKey's.
085         */
086        public static Map<EncryptionType, EncryptionKey> getKerberosKeys( String principalName, String passPhrase,
087            Set<EncryptionType> ciphers )
088        {
089            KerberosPrincipal principal = new KerberosPrincipal( principalName );
090            Map<EncryptionType, EncryptionKey> kerberosKeys = new HashMap<EncryptionType, EncryptionKey>();
091    
092            Iterator<EncryptionType> it = ciphers.iterator();
093            while ( it.hasNext() )
094            {
095                EncryptionType encryptionType = it.next();
096                String algorithm = DEFAULT_CIPHERS.get( encryptionType );
097    
098                try
099                {
100                    KerberosKey kerberosKey = new KerberosKey( principal, passPhrase.toCharArray(), algorithm );
101                    EncryptionKey encryptionKey = new EncryptionKey( encryptionType, kerberosKey.getEncoded(), kerberosKey
102                        .getVersionNumber() );
103    
104                    kerberosKeys.put( encryptionType, encryptionKey );
105                }
106                catch ( IllegalArgumentException iae )
107                {
108                    // Algorithm AES256 not enabled by policy.
109                    // Algorithm ArcFourHmac not supported by IBM JREs.
110                    // Algorithm DESede not supported by IBM JREs.
111                }
112            }
113    
114            return kerberosKeys;
115        }
116    }