package org.spongycastle.jcajce.provider.symmetric.util; import java.lang.reflect.Constructor; import java.security.InvalidKeyException; import java.security.spec.InvalidKeySpecException; import java.security.spec.KeySpec; import javax.crypto.SecretKey; import javax.crypto.SecretKeyFactorySpi; import javax.crypto.spec.DESKeySpec; import javax.crypto.spec.PBEKeySpec; import javax.crypto.spec.SecretKeySpec; import org.spongycastle.asn1.DERObjectIdentifier; import org.spongycastle.crypto.CipherParameters; import org.spongycastle.crypto.params.DESParameters; import org.spongycastle.crypto.params.KeyParameter; import org.spongycastle.crypto.params.ParametersWithIV; public class BaseSecretKeyFactory extends SecretKeyFactorySpi implements PBE { protected String algName; protected DERObjectIdentifier algOid; protected BaseSecretKeyFactory( String algName, DERObjectIdentifier algOid) { this.algName = algName; this.algOid = algOid; } protected SecretKey engineGenerateSecret( KeySpec keySpec) throws InvalidKeySpecException { if (keySpec instanceof SecretKeySpec) { return (SecretKey)keySpec; } throw new InvalidKeySpecException("Invalid KeySpec"); } protected KeySpec engineGetKeySpec( SecretKey key, Class keySpec) throws InvalidKeySpecException { if (keySpec == null) { throw new InvalidKeySpecException("keySpec parameter is null"); } if (key == null) { throw new InvalidKeySpecException("key parameter is null"); } if (SecretKeySpec.class.isAssignableFrom(keySpec)) { return new SecretKeySpec(key.getEncoded(), algName); } try { Class[] parameters = { byte[].class }; Constructor c = keySpec.getConstructor(parameters); Object[] p = new Object[1]; p[0] = key.getEncoded(); return (KeySpec)c.newInstance(p); } catch (Exception e) { throw new InvalidKeySpecException(e.toString()); } } protected SecretKey engineTranslateKey( SecretKey key) throws InvalidKeyException { if (key == null) { throw new InvalidKeyException("key parameter is null"); } if (!key.getAlgorithm().equalsIgnoreCase(algName)) { throw new InvalidKeyException("Key not of type " + algName + "."); } return new SecretKeySpec(key.getEncoded(), algName); } /* * classes that inherit from us */ static public class DESPBEKeyFactory extends BaseSecretKeyFactory { private boolean forCipher; private int scheme; private int digest; private int keySize; private int ivSize; public DESPBEKeyFactory( String algorithm, DERObjectIdentifier oid, boolean forCipher, int scheme, int digest, int keySize, int ivSize) { super(algorithm, oid); this.forCipher = forCipher; this.scheme = scheme; this.digest = digest; this.keySize = keySize; this.ivSize = ivSize; } protected SecretKey engineGenerateSecret( KeySpec keySpec) throws InvalidKeySpecException { if (keySpec instanceof PBEKeySpec) { PBEKeySpec pbeSpec = (PBEKeySpec)keySpec; CipherParameters param; if (pbeSpec.getSalt() == null) { return new BCPBEKey(this.algName, this.algOid, scheme, digest, keySize, ivSize, pbeSpec, null); } if (forCipher) { param = PBE.Util.makePBEParameters(pbeSpec, scheme, digest, keySize, ivSize); } else { param = PBE.Util.makePBEMacParameters(pbeSpec, scheme, digest, keySize); } KeyParameter kParam; if (param instanceof ParametersWithIV) { kParam = (KeyParameter)((ParametersWithIV)param).getParameters(); } else { kParam = (KeyParameter)param; } DESParameters.setOddParity(kParam.getKey()); return new BCPBEKey(this.algName, this.algOid, scheme, digest, keySize, ivSize, pbeSpec, param); } throw new InvalidKeySpecException("Invalid KeySpec"); } } static public class DES extends BaseSecretKeyFactory { public DES() { super("DES", null); } protected SecretKey engineGenerateSecret( KeySpec keySpec) throws InvalidKeySpecException { if (keySpec instanceof DESKeySpec) { DESKeySpec desKeySpec = (DESKeySpec)keySpec; return new SecretKeySpec(desKeySpec.getKey(), "DES"); } return super.engineGenerateSecret(keySpec); } } }