package com.emc.vipr.transform.encryption; import com.emc.vipr.transform.TransformConstants; import com.emc.vipr.transform.TransformException; import com.emc.vipr.transform.TransformFactory; import javax.crypto.Cipher; import javax.crypto.NoSuchPaddingException; import java.security.InvalidKeyException; import java.security.NoSuchAlgorithmException; import java.security.Provider; import java.util.Map; /** * Base class for encryption transformation factories. * * @author cwikj * * @param <T> * the class of EncryptionTransformer that the factory will produce. */ public abstract class EncryptionTransformFactory<T extends EncryptionOutputTransform, U extends EncryptionInputTransform> extends TransformFactory<T, U> { protected Provider provider; protected String encryptionTransform; protected int keySize; public EncryptionTransformFactory() throws InvalidKeyException, NoSuchAlgorithmException, NoSuchPaddingException { this(TransformConstants.DEFAULT_ENCRYPTION_TRANSFORM, TransformConstants.DEFAULT_ENCRYPTION_KEY_SIZE, null); } public EncryptionTransformFactory(String encryptionTransform, int keySize, Provider provider) throws InvalidKeyException, NoSuchAlgorithmException, NoSuchPaddingException { setEncryptionSettings(encryptionTransform, keySize, provider); setPriority(500); } public void setEncryptionSettings(String transform, int keySize, Provider provider) throws InvalidKeyException, NoSuchAlgorithmException, NoSuchPaddingException { // Check it first. if (provider != null) { Cipher.getInstance(transform, provider); } else { Cipher.getInstance(transform); } if (keySize > Cipher.getMaxAllowedKeyLength(transform)) { throw new InvalidKeyException("Key size of " + keySize + " bits is larger than the maximum allowed of " + Cipher.getMaxAllowedKeyLength(transform)); } // OK, accept settings. this.encryptionTransform = transform; this.keySize = keySize; if(provider != null) { this.provider = provider; } } public static int getMaxKeySize(String transform) throws NoSuchAlgorithmException { return Cipher.getMaxAllowedKeyLength(transform); } /** * "Rekeys" an object. This will locate the * @throws TransformException * @throws DoesNotNeedRekeyException if the object is already up to date with the * latest master key and does not need to be rekeyed. */ public abstract Map<String, String> rekey(Map<String, String> metadata) throws TransformException, DoesNotNeedRekeyException; public void setCryptoProvider(java.security.Provider provider) { this.provider = provider; } @Override public String getTransformClass() { return TransformConstants.ENCRYPTION_CLASS; } protected String getEncryptionAlgorithm() { return encryptionTransform.split("/")[0]; } }