blob: 0e6344bca3f305a61bdcb455c1b9204fe0a87d44 [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.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;
}
}