1 package org.bouncycastle.jcajce.provider.asymmetric.util; 2 3 import java.security.AlgorithmParameters; 4 import java.security.InvalidKeyException; 5 import java.security.Key; 6 import java.security.KeyFactory; 7 import java.security.NoSuchAlgorithmException; 8 import java.security.NoSuchProviderException; 9 import java.security.PrivateKey; 10 import java.security.spec.InvalidKeySpecException; 11 import java.security.spec.PKCS8EncodedKeySpec; 12 import java.security.spec.X509EncodedKeySpec; 13 14 import javax.crypto.BadPaddingException; 15 import javax.crypto.Cipher; 16 import javax.crypto.CipherSpi; 17 import javax.crypto.IllegalBlockSizeException; 18 import javax.crypto.NoSuchPaddingException; 19 import javax.crypto.spec.IvParameterSpec; 20 import javax.crypto.spec.PBEParameterSpec; 21 // BEGIN android-removed 22 // import javax.crypto.spec.RC2ParameterSpec; 23 // import javax.crypto.spec.RC5ParameterSpec; 24 // END android-removed 25 import javax.crypto.spec.SecretKeySpec; 26 27 import org.bouncycastle.asn1.pkcs.PrivateKeyInfo; 28 import org.bouncycastle.crypto.InvalidCipherTextException; 29 import org.bouncycastle.crypto.Wrapper; 30 import org.bouncycastle.jce.provider.BouncyCastleProvider; 31 32 public abstract class BaseCipherSpi 33 extends CipherSpi 34 { 35 // 36 // specs we can handle. 37 // 38 private Class[] availableSpecs = 39 { 40 IvParameterSpec.class, 41 PBEParameterSpec.class, 42 // BEGIN android-removed 43 // RC2ParameterSpec.class, 44 // RC5ParameterSpec.class 45 // END android-removed 46 }; 47 48 49 protected AlgorithmParameters engineParams = null; 50 51 protected Wrapper wrapEngine = null; 52 53 private int ivSize; 54 private byte[] iv; 55 56 protected BaseCipherSpi() 57 { 58 } 59 60 protected int engineGetBlockSize() 61 { 62 return 0; 63 } 64 65 protected byte[] engineGetIV() 66 { 67 return null; 68 } 69 70 protected int engineGetKeySize( 71 Key key) 72 { 73 return key.getEncoded().length; 74 } 75 76 protected int engineGetOutputSize( 77 int inputLen) 78 { 79 return -1; 80 } 81 82 protected AlgorithmParameters engineGetParameters() 83 { 84 return null; 85 } 86 87 protected void engineSetMode( 88 String mode) 89 throws NoSuchAlgorithmException 90 { 91 throw new NoSuchAlgorithmException("can't support mode " + mode); 92 } 93 94 protected void engineSetPadding( 95 String padding) 96 throws NoSuchPaddingException 97 { 98 throw new NoSuchPaddingException("Padding " + padding + " unknown."); 99 } 100 101 protected byte[] engineWrap( 102 Key key) 103 throws IllegalBlockSizeException, InvalidKeyException 104 { 105 byte[] encoded = key.getEncoded(); 106 if (encoded == null) 107 { 108 throw new InvalidKeyException("Cannot wrap key, null encoding."); 109 } 110 111 try 112 { 113 if (wrapEngine == null) 114 { 115 return engineDoFinal(encoded, 0, encoded.length); 116 } 117 else 118 { 119 return wrapEngine.wrap(encoded, 0, encoded.length); 120 } 121 } 122 catch (BadPaddingException e) 123 { 124 throw new IllegalBlockSizeException(e.getMessage()); 125 } 126 } 127 128 protected Key engineUnwrap( 129 byte[] wrappedKey, 130 String wrappedKeyAlgorithm, 131 int wrappedKeyType) 132 throws InvalidKeyException 133 { 134 byte[] encoded; 135 try 136 { 137 if (wrapEngine == null) 138 { 139 encoded = engineDoFinal(wrappedKey, 0, wrappedKey.length); 140 } 141 else 142 { 143 encoded = wrapEngine.unwrap(wrappedKey, 0, wrappedKey.length); 144 } 145 } 146 catch (InvalidCipherTextException e) 147 { 148 throw new InvalidKeyException(e.getMessage()); 149 } 150 catch (BadPaddingException e) 151 { 152 throw new InvalidKeyException(e.getMessage()); 153 } 154 catch (IllegalBlockSizeException e2) 155 { 156 throw new InvalidKeyException(e2.getMessage()); 157 } 158 159 if (wrappedKeyType == Cipher.SECRET_KEY) 160 { 161 return new SecretKeySpec(encoded, wrappedKeyAlgorithm); 162 } 163 else if (wrappedKeyAlgorithm.equals("") && wrappedKeyType == Cipher.PRIVATE_KEY) 164 { 165 /* 166 * The caller doesn't know the algorithm as it is part of 167 * the encrypted data. 168 */ 169 try 170 { 171 PrivateKeyInfo in = PrivateKeyInfo.getInstance(encoded); 172 173 PrivateKey privKey = BouncyCastleProvider.getPrivateKey(in); 174 175 if (privKey != null) 176 { 177 return privKey; 178 } 179 else 180 { 181 throw new InvalidKeyException("algorithm " + in.getPrivateKeyAlgorithm().getAlgorithm() + " not supported"); 182 } 183 } 184 catch (Exception e) 185 { 186 throw new InvalidKeyException("Invalid key encoding."); 187 } 188 } 189 else 190 { 191 try 192 { 193 KeyFactory kf = KeyFactory.getInstance(wrappedKeyAlgorithm, BouncyCastleProvider.PROVIDER_NAME); 194 195 if (wrappedKeyType == Cipher.PUBLIC_KEY) 196 { 197 return kf.generatePublic(new X509EncodedKeySpec(encoded)); 198 } 199 else if (wrappedKeyType == Cipher.PRIVATE_KEY) 200 { 201 return kf.generatePrivate(new PKCS8EncodedKeySpec(encoded)); 202 } 203 } 204 catch (NoSuchProviderException e) 205 { 206 throw new InvalidKeyException("Unknown key type " + e.getMessage()); 207 } 208 catch (NoSuchAlgorithmException e) 209 { 210 throw new InvalidKeyException("Unknown key type " + e.getMessage()); 211 } 212 catch (InvalidKeySpecException e2) 213 { 214 throw new InvalidKeyException("Unknown key type " + e2.getMessage()); 215 } 216 217 throw new InvalidKeyException("Unknown key type " + wrappedKeyType); 218 } 219 } 220 } 221