package org.bouncycastle.jce.provider;
import java.security.spec.AlgorithmParameterSpec;
import javax.crypto.spec.PBEKeySpec;
import javax.crypto.spec.PBEParameterSpec;
import org.bouncycastle.crypto.CipherParameters;
import org.bouncycastle.crypto.PBEParametersGenerator;
import org.bouncycastle.crypto.digests.MD2Digest;
import org.bouncycastle.crypto.digests.MD5Digest;
import org.bouncycastle.crypto.digests.RIPEMD160Digest;
import org.bouncycastle.crypto.digests.SHA1Digest;
import org.bouncycastle.crypto.digests.SHA256Digest;
import org.bouncycastle.crypto.digests.TigerDigest;
import org.bouncycastle.crypto.generators.OpenSSLPBEParametersGenerator;
import org.bouncycastle.crypto.generators.PKCS12ParametersGenerator;
import org.bouncycastle.crypto.generators.PKCS5S1ParametersGenerator;
import org.bouncycastle.crypto.generators.PKCS5S2ParametersGenerator;
import org.bouncycastle.crypto.params.DESParameters;
import org.bouncycastle.crypto.params.KeyParameter;
import org.bouncycastle.crypto.params.ParametersWithIV;
public interface PBE
{
static final int MD5 = 0;
static final int SHA1 = 1;
static final int RIPEMD160 = 2;
static final int TIGER = 3;
static final int SHA256 = 4;
static final int MD2 = 5;
static final int PKCS5S1 = 0;
static final int PKCS5S2 = 1;
static final int PKCS12 = 2;
static final int OPENSSL = 3;
static class Util
{
static private PBEParametersGenerator makePBEGenerator(
int type,
int hash)
{
PBEParametersGenerator generator;
if (type == PKCS5S1)
{
switch (hash)
{
case MD2:
generator = new PKCS5S1ParametersGenerator(new MD2Digest());
break;
case MD5:
generator = new PKCS5S1ParametersGenerator(new MD5Digest());
break;
case SHA1:
generator = new PKCS5S1ParametersGenerator(new SHA1Digest());
break;
default:
throw new IllegalStateException("PKCS5 scheme 1 only supports MD2, MD5 and SHA1.");
}
}
else if (type == PKCS5S2)
{
generator = new PKCS5S2ParametersGenerator();
}
else if (type == PKCS12)
{
switch (hash)
{
case MD2:
generator = new PKCS12ParametersGenerator(new MD2Digest());
break;
case MD5:
generator = new PKCS12ParametersGenerator(new MD5Digest());
break;
case SHA1:
generator = new PKCS12ParametersGenerator(new SHA1Digest());
break;
case RIPEMD160:
generator = new PKCS12ParametersGenerator(new RIPEMD160Digest());
break;
case TIGER:
generator = new PKCS12ParametersGenerator(new TigerDigest());
break;
case SHA256:
generator = new PKCS12ParametersGenerator(new SHA256Digest());
break;
default:
throw new IllegalStateException("unknown digest scheme for PBE encryption.");
}
}
else
{
generator = new OpenSSLPBEParametersGenerator();
}
return generator;
}
static CipherParameters makePBEParameters(
JCEPBEKey pbeKey,
AlgorithmParameterSpec spec,
String targetAlgorithm)
{
if ((spec == null) || !(spec instanceof PBEParameterSpec))
{
throw new IllegalArgumentException("Need a PBEParameter spec with a PBE key.");
}
PBEParameterSpec pbeParam = (PBEParameterSpec)spec;
PBEParametersGenerator generator = makePBEGenerator(pbeKey.getType(), pbeKey.getDigest());
byte[] key = pbeKey.getEncoded();
CipherParameters param;
if (pbeKey.shouldTryWrongPKCS12())
{
key = new byte[2];
}
generator.init(key, pbeParam.getSalt(), pbeParam.getIterationCount());
if (pbeKey.getIvSize() != 0)
{
param = generator.generateDerivedParameters(pbeKey.getKeySize(), pbeKey.getIvSize());
}
else
{
param = generator.generateDerivedParameters(pbeKey.getKeySize());
}
if (targetAlgorithm.startsWith("DES"))
{
if (param instanceof ParametersWithIV)
{
KeyParameter kParam = (KeyParameter)((ParametersWithIV)param).getParameters();
DESParameters.setOddParity(kParam.getKey());
}
else
{
KeyParameter kParam = (KeyParameter)param;
DESParameters.setOddParity(kParam.getKey());
}
}
for (int i = 0; i != key.length; i++)
{
key[i] = 0;
}
return param;
}
static CipherParameters makePBEMacParameters(
JCEPBEKey pbeKey,
AlgorithmParameterSpec spec)
{
if ((spec == null) || !(spec instanceof PBEParameterSpec))
{
throw new IllegalArgumentException("Need a PBEParameter spec with a PBE key.");
}
PBEParameterSpec pbeParam = (PBEParameterSpec)spec;
PBEParametersGenerator generator = makePBEGenerator(pbeKey.getType(), pbeKey.getDigest());
byte[] key = pbeKey.getEncoded();
CipherParameters param;
if (pbeKey.shouldTryWrongPKCS12())
{
key = new byte[2];
}
generator.init(key, pbeParam.getSalt(), pbeParam.getIterationCount());
param = generator.generateDerivedMacParameters(pbeKey.getKeySize());
for (int i = 0; i != key.length; i++)
{
key[i] = 0;
}
return param;
}
static CipherParameters makePBEParameters(
PBEKeySpec keySpec,
int type,
int hash,
int keySize,
int ivSize)
{
PBEParametersGenerator generator = makePBEGenerator(type, hash);
byte[] key;
CipherParameters param;
if (type == PKCS12)
{
key = PBEParametersGenerator.PKCS12PasswordToBytes(keySpec.getPassword());
}
else
{
key = PBEParametersGenerator.PKCS5PasswordToBytes(keySpec.getPassword());
}
generator.init(key, keySpec.getSalt(), keySpec.getIterationCount());
if (ivSize != 0)
{
param = generator.generateDerivedParameters(keySize, ivSize);
}
else
{
param = generator.generateDerivedParameters(keySize);
}
for (int i = 0; i != key.length; i++)
{
key[i] = 0;
}
return param;
}
static CipherParameters makePBEMacParameters(
PBEKeySpec keySpec,
int type,
int hash,
int keySize)
{
PBEParametersGenerator generator = makePBEGenerator(type, hash);
byte[] key;
CipherParameters param;
if (type == PKCS12)
{
key = PBEParametersGenerator.PKCS12PasswordToBytes(keySpec.getPassword());
}
else
{
key = PBEParametersGenerator.PKCS5PasswordToBytes(keySpec.getPassword());
}
generator.init(key, keySpec.getSalt(), keySpec.getIterationCount());
param = generator.generateDerivedMacParameters(keySize);
for (int i = 0; i != key.length; i++)
{
key[i] = 0;
}
return param;
}
}
}