package net.i2p.crypto;
import java.security.spec.AlgorithmParameterSpec;
import java.security.spec.InvalidParameterSpecException;
import java.util.HashMap;
import java.util.Locale;
import java.util.Map;
import net.i2p.data.Hash;
import net.i2p.data.SimpleDataStructure;
/**
* PRELIMINARY - unused - subject to change
*
* Defines the properties for various encryption types
* that I2P supports or may someday support.
*
* All PublicKeys and PrivateKeys have a type.
* Note that a EncType specifies both an algorithm and parameters, so that
* we may change primes or curves for a given algorithm.
*
* @since 0.9.18
*/
public enum EncType {
/**
* 2048-bit MODP Group from RFC 3526.
* This is the default.
* Pubkey 256 bytes, privkey 256 bytes.
*/
ELGAMAL_2048(0, 256, 256, EncAlgo.ELGAMAL, "ElGamal/None/NoPadding", CryptoConstants.I2P_ELGAMAL_2048_SPEC, "0"),
/** Pubkey 64 bytes; privkey 32 bytes; */
EC_P256(1, 64, 32, EncAlgo.EC, "EC/None/NoPadding", ECConstants.P256_SPEC, "0.9.20"),
/** Pubkey 96 bytes; privkey 48 bytes; */
EC_P384(2, 96, 48, EncAlgo.EC, "EC/None/NoPadding", ECConstants.P384_SPEC, "0.9.20"),
/** Pubkey 132 bytes; privkey 66 bytes; */
EC_P521(3, 132, 66, EncAlgo.EC, "EC/None/NoPadding", ECConstants.P521_SPEC, "0.9.20");
private final int code, pubkeyLen, privkeyLen;
private final EncAlgo base;
private final String algoName, since;
private final AlgorithmParameterSpec params;
private final boolean isAvail;
/**
*
* @param transformation algorithm/mode/padding
*
*/
EncType(int cod, int pubLen, int privLen, EncAlgo baseAlgo,
String transformation, AlgorithmParameterSpec pSpec, String supportedSince) {
code = cod;
pubkeyLen = pubLen;
privkeyLen = privLen;
base = baseAlgo;
algoName = transformation;
params = pSpec;
since = supportedSince;
isAvail = x_isAvailable();
}
/** the unique identifier for this type */
public int getCode() { return code; }
/** the length of the public key, in bytes */
public int getPubkeyLen() { return pubkeyLen; }
/** the length of the private key, in bytes */
public int getPrivkeyLen() { return privkeyLen; }
/** the standard base algorithm name used for the Java crypto factories */
public EncAlgo getBaseAlgorithm() { return base; }
/** the standard name used for the Java crypto factories */
public String getAlgorithmName() { return algoName; }
/**
* The elliptic curve ECParameterSpec for ECDSA; DSAParameterSpec for DSA
* @throws InvalidParameterSpecException if the algorithm is not available on this JVM.
*/
public AlgorithmParameterSpec getParams() throws InvalidParameterSpecException {
if (params == null)
throw new InvalidParameterSpecException(toString() + " is not available in this JVM");
return params;
}
/**
* The router version in which this type was first supported.
*/
public String getSupportedSince() {
return since;
}
/**
* @return true if supported in this JVM
*/
public boolean isAvailable() {
return isAvail;
}
private boolean x_isAvailable() {
if (ELGAMAL_2048 == this)
return true;
try {
getParams();
} catch (InvalidParameterSpecException e) {
return false;
}
return true;
}
/**
* @return true if supported in this JVM
*/
public static boolean isAvailable(int code) {
EncType type = getByCode(code);
if (type == null)
return false;
return type.isAvailable();
}
/**
* @param stype number or name
* @return true if supported in this JVM
*/
public static boolean isAvailable(String stype) {
EncType type = parseEncType(stype);
if (type == null)
return false;
return type.isAvailable();
}
private static final Map<Integer, EncType> BY_CODE = new HashMap<Integer, EncType>();
static {
for (EncType type : EncType.values()) {
if (BY_CODE.put(Integer.valueOf(type.getCode()), type) != null)
throw new IllegalStateException("Duplicate EncType code");
}
}
/** @return null if not supported */
public static EncType getByCode(int code) {
return BY_CODE.get(Integer.valueOf(code));
}
/**
* Convenience for user apps
*
* @param stype number or name
* @return null if not found
*/
public static EncType parseEncType(String stype) {
try {
String uc = stype.toUpperCase(Locale.US);
return valueOf(uc);
} catch (IllegalArgumentException iae) {
try {
int code = Integer.parseInt(stype);
return getByCode(code);
} catch (NumberFormatException nfe) {
return null;
}
}
}
}