| /** |
| * 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.kerby.kerberos.kerb.crypto; |
| |
| import org.apache.kerby.kerberos.kerb.KrbErrorCode; |
| import org.apache.kerby.kerberos.kerb.KrbException; |
| import org.apache.kerby.kerberos.kerb.crypto.enc.Aes128CtsHmacSha1Enc; |
| import org.apache.kerby.kerberos.kerb.crypto.enc.Aes256CtsHmacSha1Enc; |
| import org.apache.kerby.kerberos.kerb.crypto.enc.Camellia128CtsCmacEnc; |
| import org.apache.kerby.kerberos.kerb.crypto.enc.Camellia256CtsCmacEnc; |
| import org.apache.kerby.kerberos.kerb.crypto.enc.Des3CbcSha1Enc; |
| import org.apache.kerby.kerberos.kerb.crypto.enc.DesCbcCrcEnc; |
| import org.apache.kerby.kerberos.kerb.crypto.enc.DesCbcMd4Enc; |
| import org.apache.kerby.kerberos.kerb.crypto.enc.DesCbcMd5Enc; |
| import org.apache.kerby.kerberos.kerb.crypto.enc.Rc4HmacEnc; |
| import org.apache.kerby.kerberos.kerb.crypto.enc.Rc4HmacExpEnc; |
| import org.apache.kerby.kerberos.kerb.crypto.util.Random; |
| import org.apache.kerby.kerberos.kerb.type.base.EncryptedData; |
| import org.apache.kerby.kerberos.kerb.type.base.EncryptionKey; |
| import org.apache.kerby.kerberos.kerb.type.base.EncryptionType; |
| import org.apache.kerby.kerberos.kerb.type.base.KeyUsage; |
| import org.apache.kerby.kerberos.kerb.type.base.PrincipalName; |
| |
| /** |
| * Encryption handler as the highest level API for encryption stuffs defined in |
| * Kerberos RFC3961. It supports all the encryption types. New encryption type |
| * should be added updating this. |
| */ |
| public class EncryptionHandler { |
| |
| /** |
| * Get the encryption type. |
| * @param eType The encryption type string. |
| * @return The EncryptionType |
| * @throws KrbException e |
| */ |
| public static EncryptionType getEncryptionType(String eType) throws KrbException { |
| EncryptionType result = EncryptionType.fromName(eType); |
| return result; |
| } |
| |
| /** |
| * Get the encryption handler. |
| * |
| * @param eType The encryption type string |
| * @return The EncTypeHandler |
| * @throws KrbException e |
| */ |
| public static EncTypeHandler getEncHandler(String eType) throws KrbException { |
| EncryptionType result = EncryptionType.fromName(eType); |
| return getEncHandler(result); |
| } |
| |
| /** |
| * Get the encryption handler. |
| * |
| * @param eType The encryption type int |
| * @return The EncTypeHandler |
| * @throws KrbException e |
| */ |
| public static EncTypeHandler getEncHandler(int eType) throws KrbException { |
| EncryptionType eTypeEnum = EncryptionType.fromValue(eType); |
| return getEncHandler(eTypeEnum); |
| } |
| |
| /** |
| * Get the encryption handler. |
| * |
| * @param eType The encryption type |
| * @return The EncTypeHandler |
| * @throws KrbException e |
| */ |
| public static EncTypeHandler getEncHandler(EncryptionType eType) throws KrbException { |
| return getEncHandler(eType, false); |
| } |
| |
| /** |
| * Get the encryption handler. |
| * |
| * @param eType The encryption type |
| * @param check true if check |
| * @return The EncTypeHandler |
| * @throws KrbException e |
| */ |
| private static EncTypeHandler getEncHandler(EncryptionType eType, |
| boolean check) throws KrbException { |
| EncTypeHandler encHandler = null; |
| |
| switch (eType) { |
| case DES_CBC_CRC: |
| encHandler = new DesCbcCrcEnc(); |
| break; |
| |
| case DES_CBC_MD5: |
| case DES: |
| encHandler = new DesCbcMd5Enc(); |
| break; |
| |
| case DES_CBC_MD4: |
| encHandler = new DesCbcMd4Enc(); |
| break; |
| |
| case DES3_CBC_SHA1: |
| case DES3_CBC_SHA1_KD: |
| case DES3_HMAC_SHA1: |
| encHandler = new Des3CbcSha1Enc(); |
| break; |
| |
| case AES128_CTS_HMAC_SHA1_96: |
| case AES128_CTS: |
| encHandler = new Aes128CtsHmacSha1Enc(); |
| break; |
| |
| case AES256_CTS_HMAC_SHA1_96: |
| case AES256_CTS: |
| encHandler = new Aes256CtsHmacSha1Enc(); |
| break; |
| |
| case CAMELLIA128_CTS_CMAC: |
| case CAMELLIA128_CTS: |
| encHandler = new Camellia128CtsCmacEnc(); |
| break; |
| |
| case CAMELLIA256_CTS_CMAC: |
| case CAMELLIA256_CTS: |
| encHandler = new Camellia256CtsCmacEnc(); |
| break; |
| |
| case RC4_HMAC: |
| case ARCFOUR_HMAC: |
| case ARCFOUR_HMAC_MD5: |
| encHandler = new Rc4HmacEnc(); |
| break; |
| |
| case RC4_HMAC_EXP: |
| case ARCFOUR_HMAC_EXP: |
| case ARCFOUR_HMAC_MD5_EXP: |
| encHandler = new Rc4HmacExpEnc(); |
| break; |
| |
| case NONE: |
| default: |
| break; |
| } |
| |
| if (encHandler == null && !check) { |
| String message = "Unsupported encryption type: " + eType.name(); |
| throw new KrbException(KrbErrorCode.KDC_ERR_ETYPE_NOSUPP, message); |
| } |
| |
| return encHandler; |
| } |
| |
| /** |
| * Encrypt with the encryption key and key usage. |
| * |
| * @param plainText The plain test |
| * @param key The encryption key |
| * @param usage The key usage |
| * @return The encrypted data |
| * @throws KrbException e |
| */ |
| public static EncryptedData encrypt(byte[] plainText, EncryptionKey key, |
| KeyUsage usage) throws KrbException { |
| EncTypeHandler handler = getEncHandler(key.getKeyType()); |
| byte[] cipher = handler.encrypt(plainText, key.getKeyData(), usage.getValue()); |
| |
| EncryptedData ed = new EncryptedData(); |
| ed.setCipher(cipher); |
| ed.setEType(key.getKeyType()); |
| if (key.getKvno() > 0) { |
| ed.setKvno(key.getKvno()); |
| } |
| |
| return ed; |
| } |
| |
| /** |
| * Decrypt with the encryption key and key usage. |
| * |
| * @param data The encrypted data |
| * @param key The encryption key |
| * @param usage The key usage |
| * @return The decrypted data |
| * @throws KrbException e |
| */ |
| public static byte[] decrypt(byte[] data, EncryptionKey key, |
| KeyUsage usage) throws KrbException { |
| EncTypeHandler handler = getEncHandler(key.getKeyType()); |
| |
| byte[] plainData = handler.decrypt(data, key.getKeyData(), usage.getValue()); |
| return plainData; |
| } |
| |
| /** |
| * Decrypt with the encryption key and key usage. |
| * |
| * @param data The encrypted data |
| * @param key The encryption key |
| * @param usage The key usage |
| * @return The decrypted data |
| * @throws KrbException e |
| */ |
| public static byte[] decrypt(EncryptedData data, EncryptionKey key, |
| KeyUsage usage) throws KrbException { |
| EncTypeHandler handler = getEncHandler(key.getKeyType()); |
| |
| byte[] plainData = handler.decrypt(data.getCipher(), |
| key.getKeyData(), usage.getValue()); |
| return plainData; |
| } |
| |
| /** |
| * Return true if the the encryption handler is implemented. |
| * |
| * @param eType The encryption type |
| * @return true if the encryption handler is implemented |
| */ |
| public static boolean isImplemented(EncryptionType eType) { |
| EncTypeHandler handler = null; |
| try { |
| handler = getEncHandler(eType, true); |
| } catch (KrbException e) { |
| return false; |
| } |
| return handler != null; |
| } |
| |
| /** |
| * String to key. |
| * |
| * @param principalName The principal name |
| * @param passPhrase The pass phrase |
| * @param eType The encryption type |
| * @return The encryption key |
| * @throws KrbException e |
| */ |
| public static EncryptionKey string2Key(String principalName, |
| String passPhrase, EncryptionType eType) throws KrbException { |
| PrincipalName principal = new PrincipalName(principalName); |
| return string2Key(passPhrase, |
| PrincipalName.makeSalt(principal), null, eType); |
| } |
| |
| /** |
| * String to key. |
| * |
| * @param string The string |
| * @param salt The salt |
| * @param s2kparams The params |
| * @param eType The encryption type |
| * @return The encryption key |
| * @throws KrbException e |
| */ |
| public static EncryptionKey string2Key(String string, String salt, |
| byte[] s2kparams, EncryptionType eType) throws KrbException { |
| EncTypeHandler handler = getEncHandler(eType); |
| byte[] keyBytes = handler.str2key(string, salt, s2kparams); |
| return new EncryptionKey(eType, keyBytes); |
| } |
| |
| /** |
| * Random to key. |
| * |
| * @param eType The encryption type |
| * @return The encryption key |
| * @throws KrbException e |
| */ |
| public static EncryptionKey random2Key(EncryptionType eType) throws KrbException { |
| EncTypeHandler handler = getEncHandler(eType); |
| |
| byte[] randomBytes = Random.makeBytes(handler.keyInputSize()); |
| byte[] keyBytes = handler.random2Key(randomBytes); |
| EncryptionKey encKey = new EncryptionKey(eType, keyBytes); |
| return encKey; |
| } |
| |
| /** |
| * Random to key. |
| * |
| * @param eType The encryption type |
| * @param randomBytes The random bytes |
| * @return The encryption key |
| * @throws KrbException e |
| */ |
| public static EncryptionKey random2Key(EncryptionType eType, byte[] randomBytes) throws KrbException { |
| EncTypeHandler handler = getEncHandler(eType); |
| |
| byte[] randomBytes1 = randomBytes; |
| byte[] keyBytes = handler.random2Key(randomBytes1); |
| EncryptionKey encKey = new EncryptionKey(eType, keyBytes); |
| return encKey; |
| } |
| |
| /** |
| * Generate a secure and random key seeded with an existing encryption key. |
| * @param encKey The encryption key |
| * @return encryption key |
| */ |
| public static EncryptionKey makeSubkey(EncryptionKey encKey) { |
| //TODO: to implement. |
| return encKey; |
| } |
| } |