diff options
Diffstat (limited to 'prov/src/main/java/org/spongycastle/jcajce/provider/asymmetric/util/BaseCipherSpi.java')
-rw-r--r-- | prov/src/main/java/org/spongycastle/jcajce/provider/asymmetric/util/BaseCipherSpi.java | 216 |
1 files changed, 216 insertions, 0 deletions
diff --git a/prov/src/main/java/org/spongycastle/jcajce/provider/asymmetric/util/BaseCipherSpi.java b/prov/src/main/java/org/spongycastle/jcajce/provider/asymmetric/util/BaseCipherSpi.java new file mode 100644 index 00000000..4c1ed0ee --- /dev/null +++ b/prov/src/main/java/org/spongycastle/jcajce/provider/asymmetric/util/BaseCipherSpi.java @@ -0,0 +1,216 @@ +package org.spongycastle.jcajce.provider.asymmetric.util; + +import java.security.AlgorithmParameters; +import java.security.InvalidKeyException; +import java.security.Key; +import java.security.KeyFactory; +import java.security.NoSuchAlgorithmException; +import java.security.NoSuchProviderException; +import java.security.PrivateKey; +import java.security.spec.InvalidKeySpecException; +import java.security.spec.PKCS8EncodedKeySpec; +import java.security.spec.X509EncodedKeySpec; + +import javax.crypto.BadPaddingException; +import javax.crypto.Cipher; +import javax.crypto.CipherSpi; +import javax.crypto.IllegalBlockSizeException; +import javax.crypto.NoSuchPaddingException; +import javax.crypto.spec.IvParameterSpec; +import javax.crypto.spec.PBEParameterSpec; +import javax.crypto.spec.RC2ParameterSpec; +import javax.crypto.spec.RC5ParameterSpec; +import javax.crypto.spec.SecretKeySpec; + +import org.spongycastle.asn1.pkcs.PrivateKeyInfo; +import org.spongycastle.crypto.InvalidCipherTextException; +import org.spongycastle.crypto.Wrapper; +import org.spongycastle.jce.provider.BouncyCastleProvider; + +public abstract class BaseCipherSpi + extends CipherSpi +{ + // + // specs we can handle. + // + private Class[] availableSpecs = + { + IvParameterSpec.class, + PBEParameterSpec.class, + RC2ParameterSpec.class, + RC5ParameterSpec.class + }; + + + protected AlgorithmParameters engineParams = null; + + protected Wrapper wrapEngine = null; + + private int ivSize; + private byte[] iv; + + protected BaseCipherSpi() + { + } + + protected int engineGetBlockSize() + { + return 0; + } + + protected byte[] engineGetIV() + { + return null; + } + + protected int engineGetKeySize( + Key key) + { + return key.getEncoded().length; + } + + protected int engineGetOutputSize( + int inputLen) + { + return -1; + } + + protected AlgorithmParameters engineGetParameters() + { + return null; + } + + protected void engineSetMode( + String mode) + throws NoSuchAlgorithmException + { + throw new NoSuchAlgorithmException("can't support mode " + mode); + } + + protected void engineSetPadding( + String padding) + throws NoSuchPaddingException + { + throw new NoSuchPaddingException("Padding " + padding + " unknown."); + } + + protected byte[] engineWrap( + Key key) + throws IllegalBlockSizeException, InvalidKeyException + { + byte[] encoded = key.getEncoded(); + if (encoded == null) + { + throw new InvalidKeyException("Cannot wrap key, null encoding."); + } + + try + { + if (wrapEngine == null) + { + return engineDoFinal(encoded, 0, encoded.length); + } + else + { + return wrapEngine.wrap(encoded, 0, encoded.length); + } + } + catch (BadPaddingException e) + { + throw new IllegalBlockSizeException(e.getMessage()); + } + } + + protected Key engineUnwrap( + byte[] wrappedKey, + String wrappedKeyAlgorithm, + int wrappedKeyType) + throws InvalidKeyException + { + byte[] encoded; + try + { + if (wrapEngine == null) + { + encoded = engineDoFinal(wrappedKey, 0, wrappedKey.length); + } + else + { + encoded = wrapEngine.unwrap(wrappedKey, 0, wrappedKey.length); + } + } + catch (InvalidCipherTextException e) + { + throw new InvalidKeyException(e.getMessage()); + } + catch (BadPaddingException e) + { + throw new InvalidKeyException(e.getMessage()); + } + catch (IllegalBlockSizeException e2) + { + throw new InvalidKeyException(e2.getMessage()); + } + + if (wrappedKeyType == Cipher.SECRET_KEY) + { + return new SecretKeySpec(encoded, wrappedKeyAlgorithm); + } + else if (wrappedKeyAlgorithm.equals("") && wrappedKeyType == Cipher.PRIVATE_KEY) + { + /* + * The caller doesn't know the algorithm as it is part of + * the encrypted data. + */ + try + { + PrivateKeyInfo in = PrivateKeyInfo.getInstance(encoded); + + PrivateKey privKey = BouncyCastleProvider.getPrivateKey(in); + + if (privKey != null) + { + return privKey; + } + else + { + throw new InvalidKeyException("algorithm " + in.getPrivateKeyAlgorithm().getAlgorithm() + " not supported"); + } + } + catch (Exception e) + { + throw new InvalidKeyException("Invalid key encoding."); + } + } + else + { + try + { + KeyFactory kf = KeyFactory.getInstance(wrappedKeyAlgorithm, BouncyCastleProvider.PROVIDER_NAME); + + if (wrappedKeyType == Cipher.PUBLIC_KEY) + { + return kf.generatePublic(new X509EncodedKeySpec(encoded)); + } + else if (wrappedKeyType == Cipher.PRIVATE_KEY) + { + return kf.generatePrivate(new PKCS8EncodedKeySpec(encoded)); + } + } + catch (NoSuchProviderException e) + { + throw new InvalidKeyException("Unknown key type " + e.getMessage()); + } + catch (NoSuchAlgorithmException e) + { + throw new InvalidKeyException("Unknown key type " + e.getMessage()); + } + catch (InvalidKeySpecException e2) + { + throw new InvalidKeyException("Unknown key type " + e2.getMessage()); + } + + throw new InvalidKeyException("Unknown key type " + wrappedKeyType); + } + } +} |