14c111300c39cb2e27f07fc2ae3b00e23ed4443b2Brian Carlstrompackage org.bouncycastle.jcajce.provider.symmetric.util; 2b61a96e7ef1a78acf013bbf08fe537e5b5f129caPeter Hallam 36e736056d64d0e33b26cf9f7c4e351b496241fdeBrian Carlstromimport java.security.AlgorithmParameters; 46e736056d64d0e33b26cf9f7c4e351b496241fdeBrian Carlstromimport java.security.InvalidAlgorithmParameterException; 56e736056d64d0e33b26cf9f7c4e351b496241fdeBrian Carlstromimport java.security.InvalidKeyException; 66e736056d64d0e33b26cf9f7c4e351b496241fdeBrian Carlstromimport java.security.Key; 76e736056d64d0e33b26cf9f7c4e351b496241fdeBrian Carlstromimport java.security.KeyFactory; 86e736056d64d0e33b26cf9f7c4e351b496241fdeBrian Carlstromimport java.security.NoSuchAlgorithmException; 96e736056d64d0e33b26cf9f7c4e351b496241fdeBrian Carlstromimport java.security.NoSuchProviderException; 106e736056d64d0e33b26cf9f7c4e351b496241fdeBrian Carlstromimport java.security.PrivateKey; 11028ab6e01e3b911024b9b9243e9a0f4ac377c0faSergio Giroimport java.security.Provider; 126e736056d64d0e33b26cf9f7c4e351b496241fdeBrian Carlstromimport java.security.SecureRandom; 13028ab6e01e3b911024b9b9243e9a0f4ac377c0faSergio Giroimport java.security.Security; 146e736056d64d0e33b26cf9f7c4e351b496241fdeBrian Carlstromimport java.security.spec.AlgorithmParameterSpec; 156e736056d64d0e33b26cf9f7c4e351b496241fdeBrian Carlstromimport java.security.spec.InvalidKeySpecException; 166e736056d64d0e33b26cf9f7c4e351b496241fdeBrian Carlstromimport java.security.spec.PKCS8EncodedKeySpec; 176e736056d64d0e33b26cf9f7c4e351b496241fdeBrian Carlstromimport java.security.spec.X509EncodedKeySpec; 186e736056d64d0e33b26cf9f7c4e351b496241fdeBrian Carlstrom 196e736056d64d0e33b26cf9f7c4e351b496241fdeBrian Carlstromimport javax.crypto.BadPaddingException; 206e736056d64d0e33b26cf9f7c4e351b496241fdeBrian Carlstromimport javax.crypto.Cipher; 216e736056d64d0e33b26cf9f7c4e351b496241fdeBrian Carlstromimport javax.crypto.CipherSpi; 226e736056d64d0e33b26cf9f7c4e351b496241fdeBrian Carlstromimport javax.crypto.IllegalBlockSizeException; 236e736056d64d0e33b26cf9f7c4e351b496241fdeBrian Carlstromimport javax.crypto.NoSuchPaddingException; 246e736056d64d0e33b26cf9f7c4e351b496241fdeBrian Carlstromimport javax.crypto.ShortBufferException; 256e736056d64d0e33b26cf9f7c4e351b496241fdeBrian Carlstromimport javax.crypto.spec.IvParameterSpec; 266e736056d64d0e33b26cf9f7c4e351b496241fdeBrian Carlstromimport javax.crypto.spec.PBEParameterSpec; 276e736056d64d0e33b26cf9f7c4e351b496241fdeBrian Carlstrom// BEGIN android-removed 286e736056d64d0e33b26cf9f7c4e351b496241fdeBrian Carlstrom// import javax.crypto.spec.RC2ParameterSpec; 296e736056d64d0e33b26cf9f7c4e351b496241fdeBrian Carlstrom// import javax.crypto.spec.RC5ParameterSpec; 306e736056d64d0e33b26cf9f7c4e351b496241fdeBrian Carlstrom// END android-removed 316e736056d64d0e33b26cf9f7c4e351b496241fdeBrian Carlstromimport javax.crypto.spec.SecretKeySpec; 326e736056d64d0e33b26cf9f7c4e351b496241fdeBrian Carlstrom 33b61a96e7ef1a78acf013bbf08fe537e5b5f129caPeter Hallamimport org.bouncycastle.asn1.pkcs.PrivateKeyInfo; 34b61a96e7ef1a78acf013bbf08fe537e5b5f129caPeter Hallamimport org.bouncycastle.crypto.CipherParameters; 35b61a96e7ef1a78acf013bbf08fe537e5b5f129caPeter Hallamimport org.bouncycastle.crypto.InvalidCipherTextException; 36b61a96e7ef1a78acf013bbf08fe537e5b5f129caPeter Hallamimport org.bouncycastle.crypto.Wrapper; 37b61a96e7ef1a78acf013bbf08fe537e5b5f129caPeter Hallamimport org.bouncycastle.crypto.params.KeyParameter; 38b61a96e7ef1a78acf013bbf08fe537e5b5f129caPeter Hallamimport org.bouncycastle.crypto.params.ParametersWithIV; 39d001700a15b8bd733ae344c1fc315b97c43c6590Kenny Rootimport org.bouncycastle.crypto.params.ParametersWithRandom; 40028ab6e01e3b911024b9b9243e9a0f4ac377c0faSergio Giroimport org.bouncycastle.jcajce.util.BCJcaJceHelper; 41028ab6e01e3b911024b9b9243e9a0f4ac377c0faSergio Giroimport org.bouncycastle.jcajce.util.JcaJceHelper; 424c111300c39cb2e27f07fc2ae3b00e23ed4443b2Brian Carlstromimport org.bouncycastle.jce.provider.BouncyCastleProvider; 43b61a96e7ef1a78acf013bbf08fe537e5b5f129caPeter Hallam 444c111300c39cb2e27f07fc2ae3b00e23ed4443b2Brian Carlstrompublic abstract class BaseWrapCipher 454c111300c39cb2e27f07fc2ae3b00e23ed4443b2Brian Carlstrom extends CipherSpi 46b61a96e7ef1a78acf013bbf08fe537e5b5f129caPeter Hallam implements PBE 47b61a96e7ef1a78acf013bbf08fe537e5b5f129caPeter Hallam{ 48b61a96e7ef1a78acf013bbf08fe537e5b5f129caPeter Hallam // 49b61a96e7ef1a78acf013bbf08fe537e5b5f129caPeter Hallam // specs we can handle. 50b61a96e7ef1a78acf013bbf08fe537e5b5f129caPeter Hallam // 51b61a96e7ef1a78acf013bbf08fe537e5b5f129caPeter Hallam private Class[] availableSpecs = 52b61a96e7ef1a78acf013bbf08fe537e5b5f129caPeter Hallam { 53b61a96e7ef1a78acf013bbf08fe537e5b5f129caPeter Hallam IvParameterSpec.class, 54b61a96e7ef1a78acf013bbf08fe537e5b5f129caPeter Hallam PBEParameterSpec.class, 55c37f4a04ef89e73a39a59f3c5a179af8c8ab5974Brian Carlstrom // BEGIN android-removed 56c37f4a04ef89e73a39a59f3c5a179af8c8ab5974Brian Carlstrom // RC2ParameterSpec.class, 570d31ca0f54efe12f12049174bfa9403961654a92Brian Carlstrom // RC5ParameterSpec.class 58c37f4a04ef89e73a39a59f3c5a179af8c8ab5974Brian Carlstrom // END android-removed 59b61a96e7ef1a78acf013bbf08fe537e5b5f129caPeter Hallam }; 60b61a96e7ef1a78acf013bbf08fe537e5b5f129caPeter Hallam 61b61a96e7ef1a78acf013bbf08fe537e5b5f129caPeter Hallam protected int pbeType = PKCS12; 62b61a96e7ef1a78acf013bbf08fe537e5b5f129caPeter Hallam protected int pbeHash = SHA1; 63b61a96e7ef1a78acf013bbf08fe537e5b5f129caPeter Hallam protected int pbeKeySize; 64b61a96e7ef1a78acf013bbf08fe537e5b5f129caPeter Hallam protected int pbeIvSize; 65b61a96e7ef1a78acf013bbf08fe537e5b5f129caPeter Hallam 66b61a96e7ef1a78acf013bbf08fe537e5b5f129caPeter Hallam protected AlgorithmParameters engineParams = null; 67b61a96e7ef1a78acf013bbf08fe537e5b5f129caPeter Hallam 68c37f4a04ef89e73a39a59f3c5a179af8c8ab5974Brian Carlstrom protected Wrapper wrapEngine = null; 69c37f4a04ef89e73a39a59f3c5a179af8c8ab5974Brian Carlstrom 70c37f4a04ef89e73a39a59f3c5a179af8c8ab5974Brian Carlstrom private int ivSize; 71c37f4a04ef89e73a39a59f3c5a179af8c8ab5974Brian Carlstrom private byte[] iv; 72b61a96e7ef1a78acf013bbf08fe537e5b5f129caPeter Hallam 73028ab6e01e3b911024b9b9243e9a0f4ac377c0faSergio Giro private final JcaJceHelper helper = new BCJcaJceHelper(); 74028ab6e01e3b911024b9b9243e9a0f4ac377c0faSergio Giro 754c111300c39cb2e27f07fc2ae3b00e23ed4443b2Brian Carlstrom protected BaseWrapCipher() 76b61a96e7ef1a78acf013bbf08fe537e5b5f129caPeter Hallam { 77b61a96e7ef1a78acf013bbf08fe537e5b5f129caPeter Hallam } 78b61a96e7ef1a78acf013bbf08fe537e5b5f129caPeter Hallam 794c111300c39cb2e27f07fc2ae3b00e23ed4443b2Brian Carlstrom protected BaseWrapCipher( 80b61a96e7ef1a78acf013bbf08fe537e5b5f129caPeter Hallam Wrapper wrapEngine) 81b61a96e7ef1a78acf013bbf08fe537e5b5f129caPeter Hallam { 82c37f4a04ef89e73a39a59f3c5a179af8c8ab5974Brian Carlstrom this(wrapEngine, 0); 83c37f4a04ef89e73a39a59f3c5a179af8c8ab5974Brian Carlstrom } 84c37f4a04ef89e73a39a59f3c5a179af8c8ab5974Brian Carlstrom 854c111300c39cb2e27f07fc2ae3b00e23ed4443b2Brian Carlstrom protected BaseWrapCipher( 86c37f4a04ef89e73a39a59f3c5a179af8c8ab5974Brian Carlstrom Wrapper wrapEngine, 874c111300c39cb2e27f07fc2ae3b00e23ed4443b2Brian Carlstrom int ivSize) 88c37f4a04ef89e73a39a59f3c5a179af8c8ab5974Brian Carlstrom { 89b61a96e7ef1a78acf013bbf08fe537e5b5f129caPeter Hallam this.wrapEngine = wrapEngine; 90c37f4a04ef89e73a39a59f3c5a179af8c8ab5974Brian Carlstrom this.ivSize = ivSize; 91b61a96e7ef1a78acf013bbf08fe537e5b5f129caPeter Hallam } 92b61a96e7ef1a78acf013bbf08fe537e5b5f129caPeter Hallam 93b61a96e7ef1a78acf013bbf08fe537e5b5f129caPeter Hallam protected int engineGetBlockSize() 94b61a96e7ef1a78acf013bbf08fe537e5b5f129caPeter Hallam { 95b61a96e7ef1a78acf013bbf08fe537e5b5f129caPeter Hallam return 0; 96b61a96e7ef1a78acf013bbf08fe537e5b5f129caPeter Hallam } 97b61a96e7ef1a78acf013bbf08fe537e5b5f129caPeter Hallam 98b61a96e7ef1a78acf013bbf08fe537e5b5f129caPeter Hallam protected byte[] engineGetIV() 99b61a96e7ef1a78acf013bbf08fe537e5b5f129caPeter Hallam { 100c37f4a04ef89e73a39a59f3c5a179af8c8ab5974Brian Carlstrom return (byte[])iv.clone(); 101b61a96e7ef1a78acf013bbf08fe537e5b5f129caPeter Hallam } 102b61a96e7ef1a78acf013bbf08fe537e5b5f129caPeter Hallam 103b61a96e7ef1a78acf013bbf08fe537e5b5f129caPeter Hallam protected int engineGetKeySize( 104b61a96e7ef1a78acf013bbf08fe537e5b5f129caPeter Hallam Key key) 105b61a96e7ef1a78acf013bbf08fe537e5b5f129caPeter Hallam { 106b61a96e7ef1a78acf013bbf08fe537e5b5f129caPeter Hallam return key.getEncoded().length; 107b61a96e7ef1a78acf013bbf08fe537e5b5f129caPeter Hallam } 108b61a96e7ef1a78acf013bbf08fe537e5b5f129caPeter Hallam 109b61a96e7ef1a78acf013bbf08fe537e5b5f129caPeter Hallam protected int engineGetOutputSize( 110b61a96e7ef1a78acf013bbf08fe537e5b5f129caPeter Hallam int inputLen) 111b61a96e7ef1a78acf013bbf08fe537e5b5f129caPeter Hallam { 112b61a96e7ef1a78acf013bbf08fe537e5b5f129caPeter Hallam return -1; 113b61a96e7ef1a78acf013bbf08fe537e5b5f129caPeter Hallam } 114b61a96e7ef1a78acf013bbf08fe537e5b5f129caPeter Hallam 115b61a96e7ef1a78acf013bbf08fe537e5b5f129caPeter Hallam protected AlgorithmParameters engineGetParameters() 116b61a96e7ef1a78acf013bbf08fe537e5b5f129caPeter Hallam { 117b61a96e7ef1a78acf013bbf08fe537e5b5f129caPeter Hallam return null; 118b61a96e7ef1a78acf013bbf08fe537e5b5f129caPeter Hallam } 119b61a96e7ef1a78acf013bbf08fe537e5b5f129caPeter Hallam 120028ab6e01e3b911024b9b9243e9a0f4ac377c0faSergio Giro protected final AlgorithmParameters createParametersInstance(String algorithm) 121028ab6e01e3b911024b9b9243e9a0f4ac377c0faSergio Giro throws NoSuchAlgorithmException, NoSuchProviderException 122028ab6e01e3b911024b9b9243e9a0f4ac377c0faSergio Giro { 123028ab6e01e3b911024b9b9243e9a0f4ac377c0faSergio Giro return helper.createAlgorithmParameters(algorithm); 124028ab6e01e3b911024b9b9243e9a0f4ac377c0faSergio Giro } 125028ab6e01e3b911024b9b9243e9a0f4ac377c0faSergio Giro 126b61a96e7ef1a78acf013bbf08fe537e5b5f129caPeter Hallam protected void engineSetMode( 127b61a96e7ef1a78acf013bbf08fe537e5b5f129caPeter Hallam String mode) 128b61a96e7ef1a78acf013bbf08fe537e5b5f129caPeter Hallam throws NoSuchAlgorithmException 129b61a96e7ef1a78acf013bbf08fe537e5b5f129caPeter Hallam { 130b61a96e7ef1a78acf013bbf08fe537e5b5f129caPeter Hallam throw new NoSuchAlgorithmException("can't support mode " + mode); 131b61a96e7ef1a78acf013bbf08fe537e5b5f129caPeter Hallam } 132b61a96e7ef1a78acf013bbf08fe537e5b5f129caPeter Hallam 133b61a96e7ef1a78acf013bbf08fe537e5b5f129caPeter Hallam protected void engineSetPadding( 134b61a96e7ef1a78acf013bbf08fe537e5b5f129caPeter Hallam String padding) 135b61a96e7ef1a78acf013bbf08fe537e5b5f129caPeter Hallam throws NoSuchPaddingException 136b61a96e7ef1a78acf013bbf08fe537e5b5f129caPeter Hallam { 137b61a96e7ef1a78acf013bbf08fe537e5b5f129caPeter Hallam throw new NoSuchPaddingException("Padding " + padding + " unknown."); 138b61a96e7ef1a78acf013bbf08fe537e5b5f129caPeter Hallam } 139b61a96e7ef1a78acf013bbf08fe537e5b5f129caPeter Hallam 140b61a96e7ef1a78acf013bbf08fe537e5b5f129caPeter Hallam protected void engineInit( 141b61a96e7ef1a78acf013bbf08fe537e5b5f129caPeter Hallam int opmode, 142b61a96e7ef1a78acf013bbf08fe537e5b5f129caPeter Hallam Key key, 143b61a96e7ef1a78acf013bbf08fe537e5b5f129caPeter Hallam AlgorithmParameterSpec params, 144b61a96e7ef1a78acf013bbf08fe537e5b5f129caPeter Hallam SecureRandom random) 145b61a96e7ef1a78acf013bbf08fe537e5b5f129caPeter Hallam throws InvalidKeyException, InvalidAlgorithmParameterException 146b61a96e7ef1a78acf013bbf08fe537e5b5f129caPeter Hallam { 147b61a96e7ef1a78acf013bbf08fe537e5b5f129caPeter Hallam CipherParameters param; 148b61a96e7ef1a78acf013bbf08fe537e5b5f129caPeter Hallam 1494c111300c39cb2e27f07fc2ae3b00e23ed4443b2Brian Carlstrom if (key instanceof BCPBEKey) 150b61a96e7ef1a78acf013bbf08fe537e5b5f129caPeter Hallam { 1514c111300c39cb2e27f07fc2ae3b00e23ed4443b2Brian Carlstrom BCPBEKey k = (BCPBEKey)key; 1524c111300c39cb2e27f07fc2ae3b00e23ed4443b2Brian Carlstrom 153b61a96e7ef1a78acf013bbf08fe537e5b5f129caPeter Hallam if (params instanceof PBEParameterSpec) 154b61a96e7ef1a78acf013bbf08fe537e5b5f129caPeter Hallam { 155b61a96e7ef1a78acf013bbf08fe537e5b5f129caPeter Hallam param = PBE.Util.makePBEParameters(k, params, wrapEngine.getAlgorithmName()); 156b61a96e7ef1a78acf013bbf08fe537e5b5f129caPeter Hallam } 157b61a96e7ef1a78acf013bbf08fe537e5b5f129caPeter Hallam else if (k.getParam() != null) 158b61a96e7ef1a78acf013bbf08fe537e5b5f129caPeter Hallam { 159b61a96e7ef1a78acf013bbf08fe537e5b5f129caPeter Hallam param = k.getParam(); 160b61a96e7ef1a78acf013bbf08fe537e5b5f129caPeter Hallam } 161b61a96e7ef1a78acf013bbf08fe537e5b5f129caPeter Hallam else 162b61a96e7ef1a78acf013bbf08fe537e5b5f129caPeter Hallam { 163b61a96e7ef1a78acf013bbf08fe537e5b5f129caPeter Hallam throw new InvalidAlgorithmParameterException("PBE requires PBE parameters to be set."); 164b61a96e7ef1a78acf013bbf08fe537e5b5f129caPeter Hallam } 165b61a96e7ef1a78acf013bbf08fe537e5b5f129caPeter Hallam } 166b61a96e7ef1a78acf013bbf08fe537e5b5f129caPeter Hallam else 167b61a96e7ef1a78acf013bbf08fe537e5b5f129caPeter Hallam { 168b61a96e7ef1a78acf013bbf08fe537e5b5f129caPeter Hallam param = new KeyParameter(key.getEncoded()); 169b61a96e7ef1a78acf013bbf08fe537e5b5f129caPeter Hallam } 170b61a96e7ef1a78acf013bbf08fe537e5b5f129caPeter Hallam 1714c111300c39cb2e27f07fc2ae3b00e23ed4443b2Brian Carlstrom if (params instanceof IvParameterSpec) 172b61a96e7ef1a78acf013bbf08fe537e5b5f129caPeter Hallam { 173b61a96e7ef1a78acf013bbf08fe537e5b5f129caPeter Hallam IvParameterSpec iv = (IvParameterSpec) params; 174c37f4a04ef89e73a39a59f3c5a179af8c8ab5974Brian Carlstrom param = new ParametersWithIV(param, iv.getIV()); 175c37f4a04ef89e73a39a59f3c5a179af8c8ab5974Brian Carlstrom } 176c37f4a04ef89e73a39a59f3c5a179af8c8ab5974Brian Carlstrom 177c37f4a04ef89e73a39a59f3c5a179af8c8ab5974Brian Carlstrom if (param instanceof KeyParameter && ivSize != 0) 178c37f4a04ef89e73a39a59f3c5a179af8c8ab5974Brian Carlstrom { 179c37f4a04ef89e73a39a59f3c5a179af8c8ab5974Brian Carlstrom iv = new byte[ivSize]; 180c37f4a04ef89e73a39a59f3c5a179af8c8ab5974Brian Carlstrom random.nextBytes(iv); 181c37f4a04ef89e73a39a59f3c5a179af8c8ab5974Brian Carlstrom param = new ParametersWithIV(param, iv); 182b61a96e7ef1a78acf013bbf08fe537e5b5f129caPeter Hallam } 183b61a96e7ef1a78acf013bbf08fe537e5b5f129caPeter Hallam 184d001700a15b8bd733ae344c1fc315b97c43c6590Kenny Root if (random != null) 185d001700a15b8bd733ae344c1fc315b97c43c6590Kenny Root { 186d001700a15b8bd733ae344c1fc315b97c43c6590Kenny Root param = new ParametersWithRandom(param, random); 187d001700a15b8bd733ae344c1fc315b97c43c6590Kenny Root } 188d001700a15b8bd733ae344c1fc315b97c43c6590Kenny Root 189b61a96e7ef1a78acf013bbf08fe537e5b5f129caPeter Hallam switch (opmode) 190b61a96e7ef1a78acf013bbf08fe537e5b5f129caPeter Hallam { 191b61a96e7ef1a78acf013bbf08fe537e5b5f129caPeter Hallam case Cipher.WRAP_MODE: 192b61a96e7ef1a78acf013bbf08fe537e5b5f129caPeter Hallam wrapEngine.init(true, param); 193b61a96e7ef1a78acf013bbf08fe537e5b5f129caPeter Hallam break; 194b61a96e7ef1a78acf013bbf08fe537e5b5f129caPeter Hallam case Cipher.UNWRAP_MODE: 195b61a96e7ef1a78acf013bbf08fe537e5b5f129caPeter Hallam wrapEngine.init(false, param); 196b61a96e7ef1a78acf013bbf08fe537e5b5f129caPeter Hallam break; 197b61a96e7ef1a78acf013bbf08fe537e5b5f129caPeter Hallam case Cipher.ENCRYPT_MODE: 198b61a96e7ef1a78acf013bbf08fe537e5b5f129caPeter Hallam case Cipher.DECRYPT_MODE: 199b61a96e7ef1a78acf013bbf08fe537e5b5f129caPeter Hallam throw new IllegalArgumentException("engine only valid for wrapping"); 200b61a96e7ef1a78acf013bbf08fe537e5b5f129caPeter Hallam default: 201b61a96e7ef1a78acf013bbf08fe537e5b5f129caPeter Hallam System.out.println("eeek!"); 202b61a96e7ef1a78acf013bbf08fe537e5b5f129caPeter Hallam } 203b61a96e7ef1a78acf013bbf08fe537e5b5f129caPeter Hallam } 204b61a96e7ef1a78acf013bbf08fe537e5b5f129caPeter Hallam 205b61a96e7ef1a78acf013bbf08fe537e5b5f129caPeter Hallam protected void engineInit( 206b61a96e7ef1a78acf013bbf08fe537e5b5f129caPeter Hallam int opmode, 207b61a96e7ef1a78acf013bbf08fe537e5b5f129caPeter Hallam Key key, 208b61a96e7ef1a78acf013bbf08fe537e5b5f129caPeter Hallam AlgorithmParameters params, 209b61a96e7ef1a78acf013bbf08fe537e5b5f129caPeter Hallam SecureRandom random) 210b61a96e7ef1a78acf013bbf08fe537e5b5f129caPeter Hallam throws InvalidKeyException, InvalidAlgorithmParameterException 211b61a96e7ef1a78acf013bbf08fe537e5b5f129caPeter Hallam { 212b61a96e7ef1a78acf013bbf08fe537e5b5f129caPeter Hallam AlgorithmParameterSpec paramSpec = null; 213b61a96e7ef1a78acf013bbf08fe537e5b5f129caPeter Hallam 214b61a96e7ef1a78acf013bbf08fe537e5b5f129caPeter Hallam if (params != null) 215b61a96e7ef1a78acf013bbf08fe537e5b5f129caPeter Hallam { 216b61a96e7ef1a78acf013bbf08fe537e5b5f129caPeter Hallam for (int i = 0; i != availableSpecs.length; i++) 217b61a96e7ef1a78acf013bbf08fe537e5b5f129caPeter Hallam { 218b61a96e7ef1a78acf013bbf08fe537e5b5f129caPeter Hallam try 219b61a96e7ef1a78acf013bbf08fe537e5b5f129caPeter Hallam { 220b61a96e7ef1a78acf013bbf08fe537e5b5f129caPeter Hallam paramSpec = params.getParameterSpec(availableSpecs[i]); 221b61a96e7ef1a78acf013bbf08fe537e5b5f129caPeter Hallam break; 222b61a96e7ef1a78acf013bbf08fe537e5b5f129caPeter Hallam } 223b61a96e7ef1a78acf013bbf08fe537e5b5f129caPeter Hallam catch (Exception e) 224b61a96e7ef1a78acf013bbf08fe537e5b5f129caPeter Hallam { 225c37f4a04ef89e73a39a59f3c5a179af8c8ab5974Brian Carlstrom // try next spec 226b61a96e7ef1a78acf013bbf08fe537e5b5f129caPeter Hallam } 227b61a96e7ef1a78acf013bbf08fe537e5b5f129caPeter Hallam } 228b61a96e7ef1a78acf013bbf08fe537e5b5f129caPeter Hallam 229b61a96e7ef1a78acf013bbf08fe537e5b5f129caPeter Hallam if (paramSpec == null) 230b61a96e7ef1a78acf013bbf08fe537e5b5f129caPeter Hallam { 231b61a96e7ef1a78acf013bbf08fe537e5b5f129caPeter Hallam throw new InvalidAlgorithmParameterException("can't handle parameter " + params.toString()); 232b61a96e7ef1a78acf013bbf08fe537e5b5f129caPeter Hallam } 233b61a96e7ef1a78acf013bbf08fe537e5b5f129caPeter Hallam } 234b61a96e7ef1a78acf013bbf08fe537e5b5f129caPeter Hallam 235b61a96e7ef1a78acf013bbf08fe537e5b5f129caPeter Hallam engineParams = params; 236b61a96e7ef1a78acf013bbf08fe537e5b5f129caPeter Hallam engineInit(opmode, key, paramSpec, random); 237b61a96e7ef1a78acf013bbf08fe537e5b5f129caPeter Hallam } 238b61a96e7ef1a78acf013bbf08fe537e5b5f129caPeter Hallam 239b61a96e7ef1a78acf013bbf08fe537e5b5f129caPeter Hallam protected void engineInit( 240b61a96e7ef1a78acf013bbf08fe537e5b5f129caPeter Hallam int opmode, 241b61a96e7ef1a78acf013bbf08fe537e5b5f129caPeter Hallam Key key, 242b61a96e7ef1a78acf013bbf08fe537e5b5f129caPeter Hallam SecureRandom random) 243b61a96e7ef1a78acf013bbf08fe537e5b5f129caPeter Hallam throws InvalidKeyException 244b61a96e7ef1a78acf013bbf08fe537e5b5f129caPeter Hallam { 245b61a96e7ef1a78acf013bbf08fe537e5b5f129caPeter Hallam try 246b61a96e7ef1a78acf013bbf08fe537e5b5f129caPeter Hallam { 247b61a96e7ef1a78acf013bbf08fe537e5b5f129caPeter Hallam engineInit(opmode, key, (AlgorithmParameterSpec)null, random); 248b61a96e7ef1a78acf013bbf08fe537e5b5f129caPeter Hallam } 249b61a96e7ef1a78acf013bbf08fe537e5b5f129caPeter Hallam catch (InvalidAlgorithmParameterException e) 250b61a96e7ef1a78acf013bbf08fe537e5b5f129caPeter Hallam { 251b61a96e7ef1a78acf013bbf08fe537e5b5f129caPeter Hallam throw new IllegalArgumentException(e.getMessage()); 252b61a96e7ef1a78acf013bbf08fe537e5b5f129caPeter Hallam } 253b61a96e7ef1a78acf013bbf08fe537e5b5f129caPeter Hallam } 254b61a96e7ef1a78acf013bbf08fe537e5b5f129caPeter Hallam 255b61a96e7ef1a78acf013bbf08fe537e5b5f129caPeter Hallam protected byte[] engineUpdate( 256b61a96e7ef1a78acf013bbf08fe537e5b5f129caPeter Hallam byte[] input, 257b61a96e7ef1a78acf013bbf08fe537e5b5f129caPeter Hallam int inputOffset, 258b61a96e7ef1a78acf013bbf08fe537e5b5f129caPeter Hallam int inputLen) 259b61a96e7ef1a78acf013bbf08fe537e5b5f129caPeter Hallam { 260b61a96e7ef1a78acf013bbf08fe537e5b5f129caPeter Hallam throw new RuntimeException("not supported for wrapping"); 261b61a96e7ef1a78acf013bbf08fe537e5b5f129caPeter Hallam } 262b61a96e7ef1a78acf013bbf08fe537e5b5f129caPeter Hallam 263b61a96e7ef1a78acf013bbf08fe537e5b5f129caPeter Hallam protected int engineUpdate( 264b61a96e7ef1a78acf013bbf08fe537e5b5f129caPeter Hallam byte[] input, 265b61a96e7ef1a78acf013bbf08fe537e5b5f129caPeter Hallam int inputOffset, 266b61a96e7ef1a78acf013bbf08fe537e5b5f129caPeter Hallam int inputLen, 267b61a96e7ef1a78acf013bbf08fe537e5b5f129caPeter Hallam byte[] output, 268b61a96e7ef1a78acf013bbf08fe537e5b5f129caPeter Hallam int outputOffset) 269b61a96e7ef1a78acf013bbf08fe537e5b5f129caPeter Hallam throws ShortBufferException 270b61a96e7ef1a78acf013bbf08fe537e5b5f129caPeter Hallam { 271b61a96e7ef1a78acf013bbf08fe537e5b5f129caPeter Hallam throw new RuntimeException("not supported for wrapping"); 272b61a96e7ef1a78acf013bbf08fe537e5b5f129caPeter Hallam } 273b61a96e7ef1a78acf013bbf08fe537e5b5f129caPeter Hallam 274b61a96e7ef1a78acf013bbf08fe537e5b5f129caPeter Hallam protected byte[] engineDoFinal( 275b61a96e7ef1a78acf013bbf08fe537e5b5f129caPeter Hallam byte[] input, 276b61a96e7ef1a78acf013bbf08fe537e5b5f129caPeter Hallam int inputOffset, 277b61a96e7ef1a78acf013bbf08fe537e5b5f129caPeter Hallam int inputLen) 278b61a96e7ef1a78acf013bbf08fe537e5b5f129caPeter Hallam throws IllegalBlockSizeException, BadPaddingException 279b61a96e7ef1a78acf013bbf08fe537e5b5f129caPeter Hallam { 280b61a96e7ef1a78acf013bbf08fe537e5b5f129caPeter Hallam return null; 281b61a96e7ef1a78acf013bbf08fe537e5b5f129caPeter Hallam } 282b61a96e7ef1a78acf013bbf08fe537e5b5f129caPeter Hallam 283b61a96e7ef1a78acf013bbf08fe537e5b5f129caPeter Hallam // BEGIN android-changed 284b61a96e7ef1a78acf013bbf08fe537e5b5f129caPeter Hallam // added ShortBufferException to throws statement 285b61a96e7ef1a78acf013bbf08fe537e5b5f129caPeter Hallam protected int engineDoFinal( 286b61a96e7ef1a78acf013bbf08fe537e5b5f129caPeter Hallam byte[] input, 287b61a96e7ef1a78acf013bbf08fe537e5b5f129caPeter Hallam int inputOffset, 288b61a96e7ef1a78acf013bbf08fe537e5b5f129caPeter Hallam int inputLen, 289b61a96e7ef1a78acf013bbf08fe537e5b5f129caPeter Hallam byte[] output, 290b61a96e7ef1a78acf013bbf08fe537e5b5f129caPeter Hallam int outputOffset) 291b61a96e7ef1a78acf013bbf08fe537e5b5f129caPeter Hallam throws IllegalBlockSizeException, BadPaddingException, ShortBufferException 292b61a96e7ef1a78acf013bbf08fe537e5b5f129caPeter Hallam { 293b61a96e7ef1a78acf013bbf08fe537e5b5f129caPeter Hallam return 0; 294b61a96e7ef1a78acf013bbf08fe537e5b5f129caPeter Hallam } 295b61a96e7ef1a78acf013bbf08fe537e5b5f129caPeter Hallam // END android-changed 296b61a96e7ef1a78acf013bbf08fe537e5b5f129caPeter Hallam 297b61a96e7ef1a78acf013bbf08fe537e5b5f129caPeter Hallam protected byte[] engineWrap( 298b61a96e7ef1a78acf013bbf08fe537e5b5f129caPeter Hallam Key key) 2994c111300c39cb2e27f07fc2ae3b00e23ed4443b2Brian Carlstrom throws IllegalBlockSizeException, InvalidKeyException 300b61a96e7ef1a78acf013bbf08fe537e5b5f129caPeter Hallam { 301b61a96e7ef1a78acf013bbf08fe537e5b5f129caPeter Hallam byte[] encoded = key.getEncoded(); 302b61a96e7ef1a78acf013bbf08fe537e5b5f129caPeter Hallam if (encoded == null) 303b61a96e7ef1a78acf013bbf08fe537e5b5f129caPeter Hallam { 304b61a96e7ef1a78acf013bbf08fe537e5b5f129caPeter Hallam throw new InvalidKeyException("Cannot wrap key, null encoding."); 305b61a96e7ef1a78acf013bbf08fe537e5b5f129caPeter Hallam } 306b61a96e7ef1a78acf013bbf08fe537e5b5f129caPeter Hallam 307b61a96e7ef1a78acf013bbf08fe537e5b5f129caPeter Hallam try 308b61a96e7ef1a78acf013bbf08fe537e5b5f129caPeter Hallam { 309b61a96e7ef1a78acf013bbf08fe537e5b5f129caPeter Hallam if (wrapEngine == null) 310b61a96e7ef1a78acf013bbf08fe537e5b5f129caPeter Hallam { 311b61a96e7ef1a78acf013bbf08fe537e5b5f129caPeter Hallam return engineDoFinal(encoded, 0, encoded.length); 312b61a96e7ef1a78acf013bbf08fe537e5b5f129caPeter Hallam } 313b61a96e7ef1a78acf013bbf08fe537e5b5f129caPeter Hallam else 314b61a96e7ef1a78acf013bbf08fe537e5b5f129caPeter Hallam { 315b61a96e7ef1a78acf013bbf08fe537e5b5f129caPeter Hallam return wrapEngine.wrap(encoded, 0, encoded.length); 316b61a96e7ef1a78acf013bbf08fe537e5b5f129caPeter Hallam } 317b61a96e7ef1a78acf013bbf08fe537e5b5f129caPeter Hallam } 318b61a96e7ef1a78acf013bbf08fe537e5b5f129caPeter Hallam catch (BadPaddingException e) 319b61a96e7ef1a78acf013bbf08fe537e5b5f129caPeter Hallam { 320b61a96e7ef1a78acf013bbf08fe537e5b5f129caPeter Hallam throw new IllegalBlockSizeException(e.getMessage()); 321b61a96e7ef1a78acf013bbf08fe537e5b5f129caPeter Hallam } 322b61a96e7ef1a78acf013bbf08fe537e5b5f129caPeter Hallam } 323b61a96e7ef1a78acf013bbf08fe537e5b5f129caPeter Hallam 324b61a96e7ef1a78acf013bbf08fe537e5b5f129caPeter Hallam protected Key engineUnwrap( 325b61a96e7ef1a78acf013bbf08fe537e5b5f129caPeter Hallam byte[] wrappedKey, 326b61a96e7ef1a78acf013bbf08fe537e5b5f129caPeter Hallam String wrappedKeyAlgorithm, 327b61a96e7ef1a78acf013bbf08fe537e5b5f129caPeter Hallam int wrappedKeyType) 328b61a96e7ef1a78acf013bbf08fe537e5b5f129caPeter Hallam throws InvalidKeyException, NoSuchAlgorithmException 329b61a96e7ef1a78acf013bbf08fe537e5b5f129caPeter Hallam { 330c37f4a04ef89e73a39a59f3c5a179af8c8ab5974Brian Carlstrom byte[] encoded; 331b61a96e7ef1a78acf013bbf08fe537e5b5f129caPeter Hallam try 332b61a96e7ef1a78acf013bbf08fe537e5b5f129caPeter Hallam { 333b61a96e7ef1a78acf013bbf08fe537e5b5f129caPeter Hallam if (wrapEngine == null) 334b61a96e7ef1a78acf013bbf08fe537e5b5f129caPeter Hallam { 335b61a96e7ef1a78acf013bbf08fe537e5b5f129caPeter Hallam encoded = engineDoFinal(wrappedKey, 0, wrappedKey.length); 336b61a96e7ef1a78acf013bbf08fe537e5b5f129caPeter Hallam } 337b61a96e7ef1a78acf013bbf08fe537e5b5f129caPeter Hallam else 338b61a96e7ef1a78acf013bbf08fe537e5b5f129caPeter Hallam { 339b61a96e7ef1a78acf013bbf08fe537e5b5f129caPeter Hallam encoded = wrapEngine.unwrap(wrappedKey, 0, wrappedKey.length); 340b61a96e7ef1a78acf013bbf08fe537e5b5f129caPeter Hallam } 341b61a96e7ef1a78acf013bbf08fe537e5b5f129caPeter Hallam } 342b61a96e7ef1a78acf013bbf08fe537e5b5f129caPeter Hallam catch (InvalidCipherTextException e) 343b61a96e7ef1a78acf013bbf08fe537e5b5f129caPeter Hallam { 344b61a96e7ef1a78acf013bbf08fe537e5b5f129caPeter Hallam throw new InvalidKeyException(e.getMessage()); 345b61a96e7ef1a78acf013bbf08fe537e5b5f129caPeter Hallam } 346b61a96e7ef1a78acf013bbf08fe537e5b5f129caPeter Hallam catch (BadPaddingException e) 347b61a96e7ef1a78acf013bbf08fe537e5b5f129caPeter Hallam { 348b61a96e7ef1a78acf013bbf08fe537e5b5f129caPeter Hallam throw new InvalidKeyException(e.getMessage()); 349b61a96e7ef1a78acf013bbf08fe537e5b5f129caPeter Hallam } 350b61a96e7ef1a78acf013bbf08fe537e5b5f129caPeter Hallam catch (IllegalBlockSizeException e2) 351b61a96e7ef1a78acf013bbf08fe537e5b5f129caPeter Hallam { 352b61a96e7ef1a78acf013bbf08fe537e5b5f129caPeter Hallam throw new InvalidKeyException(e2.getMessage()); 353b61a96e7ef1a78acf013bbf08fe537e5b5f129caPeter Hallam } 354b61a96e7ef1a78acf013bbf08fe537e5b5f129caPeter Hallam 355b61a96e7ef1a78acf013bbf08fe537e5b5f129caPeter Hallam if (wrappedKeyType == Cipher.SECRET_KEY) 356b61a96e7ef1a78acf013bbf08fe537e5b5f129caPeter Hallam { 357b61a96e7ef1a78acf013bbf08fe537e5b5f129caPeter Hallam return new SecretKeySpec(encoded, wrappedKeyAlgorithm); 358b61a96e7ef1a78acf013bbf08fe537e5b5f129caPeter Hallam } 359b61a96e7ef1a78acf013bbf08fe537e5b5f129caPeter Hallam else if (wrappedKeyAlgorithm.equals("") && wrappedKeyType == Cipher.PRIVATE_KEY) 360b61a96e7ef1a78acf013bbf08fe537e5b5f129caPeter Hallam { 361b61a96e7ef1a78acf013bbf08fe537e5b5f129caPeter Hallam /* 36270c8287138e69a98c2f950036f9f703ee37228c8Brian Carlstrom * The caller doesn't know the algorithm as it is part of 36370c8287138e69a98c2f950036f9f703ee37228c8Brian Carlstrom * the encrypted data. 36470c8287138e69a98c2f950036f9f703ee37228c8Brian Carlstrom */ 365b61a96e7ef1a78acf013bbf08fe537e5b5f129caPeter Hallam try 366b61a96e7ef1a78acf013bbf08fe537e5b5f129caPeter Hallam { 3674c111300c39cb2e27f07fc2ae3b00e23ed4443b2Brian Carlstrom PrivateKeyInfo in = PrivateKeyInfo.getInstance(encoded); 368b61a96e7ef1a78acf013bbf08fe537e5b5f129caPeter Hallam 3694c111300c39cb2e27f07fc2ae3b00e23ed4443b2Brian Carlstrom PrivateKey privKey = BouncyCastleProvider.getPrivateKey(in); 370b61a96e7ef1a78acf013bbf08fe537e5b5f129caPeter Hallam 3714c111300c39cb2e27f07fc2ae3b00e23ed4443b2Brian Carlstrom if (privKey != null) 372b61a96e7ef1a78acf013bbf08fe537e5b5f129caPeter Hallam { 3734c111300c39cb2e27f07fc2ae3b00e23ed4443b2Brian Carlstrom return privKey; 374b61a96e7ef1a78acf013bbf08fe537e5b5f129caPeter Hallam } 3754c111300c39cb2e27f07fc2ae3b00e23ed4443b2Brian Carlstrom else 376b61a96e7ef1a78acf013bbf08fe537e5b5f129caPeter Hallam { 3774c111300c39cb2e27f07fc2ae3b00e23ed4443b2Brian Carlstrom throw new InvalidKeyException("algorithm " + in.getPrivateKeyAlgorithm().getAlgorithm() + " not supported"); 378b61a96e7ef1a78acf013bbf08fe537e5b5f129caPeter Hallam } 379b61a96e7ef1a78acf013bbf08fe537e5b5f129caPeter Hallam } 380b61a96e7ef1a78acf013bbf08fe537e5b5f129caPeter Hallam catch (Exception e) 381b61a96e7ef1a78acf013bbf08fe537e5b5f129caPeter Hallam { 382b61a96e7ef1a78acf013bbf08fe537e5b5f129caPeter Hallam throw new InvalidKeyException("Invalid key encoding."); 383b61a96e7ef1a78acf013bbf08fe537e5b5f129caPeter Hallam } 384b61a96e7ef1a78acf013bbf08fe537e5b5f129caPeter Hallam } 385b61a96e7ef1a78acf013bbf08fe537e5b5f129caPeter Hallam else 386b61a96e7ef1a78acf013bbf08fe537e5b5f129caPeter Hallam { 387b61a96e7ef1a78acf013bbf08fe537e5b5f129caPeter Hallam try 388b61a96e7ef1a78acf013bbf08fe537e5b5f129caPeter Hallam { 389028ab6e01e3b911024b9b9243e9a0f4ac377c0faSergio Giro KeyFactory kf = helper.createKeyFactory(wrappedKeyAlgorithm); 390b61a96e7ef1a78acf013bbf08fe537e5b5f129caPeter Hallam 391b61a96e7ef1a78acf013bbf08fe537e5b5f129caPeter Hallam if (wrappedKeyType == Cipher.PUBLIC_KEY) 392b61a96e7ef1a78acf013bbf08fe537e5b5f129caPeter Hallam { 393b61a96e7ef1a78acf013bbf08fe537e5b5f129caPeter Hallam return kf.generatePublic(new X509EncodedKeySpec(encoded)); 394b61a96e7ef1a78acf013bbf08fe537e5b5f129caPeter Hallam } 395b61a96e7ef1a78acf013bbf08fe537e5b5f129caPeter Hallam else if (wrappedKeyType == Cipher.PRIVATE_KEY) 396b61a96e7ef1a78acf013bbf08fe537e5b5f129caPeter Hallam { 397b61a96e7ef1a78acf013bbf08fe537e5b5f129caPeter Hallam return kf.generatePrivate(new PKCS8EncodedKeySpec(encoded)); 398b61a96e7ef1a78acf013bbf08fe537e5b5f129caPeter Hallam } 399b61a96e7ef1a78acf013bbf08fe537e5b5f129caPeter Hallam } 400b61a96e7ef1a78acf013bbf08fe537e5b5f129caPeter Hallam catch (NoSuchProviderException e) 401b61a96e7ef1a78acf013bbf08fe537e5b5f129caPeter Hallam { 402b61a96e7ef1a78acf013bbf08fe537e5b5f129caPeter Hallam throw new InvalidKeyException("Unknown key type " + e.getMessage()); 403b61a96e7ef1a78acf013bbf08fe537e5b5f129caPeter Hallam } 404b61a96e7ef1a78acf013bbf08fe537e5b5f129caPeter Hallam catch (InvalidKeySpecException e2) 405b61a96e7ef1a78acf013bbf08fe537e5b5f129caPeter Hallam { 406b61a96e7ef1a78acf013bbf08fe537e5b5f129caPeter Hallam throw new InvalidKeyException("Unknown key type " + e2.getMessage()); 407b61a96e7ef1a78acf013bbf08fe537e5b5f129caPeter Hallam } 408b61a96e7ef1a78acf013bbf08fe537e5b5f129caPeter Hallam 409b61a96e7ef1a78acf013bbf08fe537e5b5f129caPeter Hallam throw new InvalidKeyException("Unknown key type " + wrappedKeyType); 410b61a96e7ef1a78acf013bbf08fe537e5b5f129caPeter Hallam } 411b61a96e7ef1a78acf013bbf08fe537e5b5f129caPeter Hallam } 412b61a96e7ef1a78acf013bbf08fe537e5b5f129caPeter Hallam 413b61a96e7ef1a78acf013bbf08fe537e5b5f129caPeter Hallam} 414