BaseWrapCipher.java revision 4c111300c39cb2e27f07fc2ae3b00e23ed4443b2
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; 116e736056d64d0e33b26cf9f7c4e351b496241fdeBrian Carlstromimport java.security.SecureRandom; 126e736056d64d0e33b26cf9f7c4e351b496241fdeBrian Carlstromimport java.security.spec.AlgorithmParameterSpec; 136e736056d64d0e33b26cf9f7c4e351b496241fdeBrian Carlstromimport java.security.spec.InvalidKeySpecException; 146e736056d64d0e33b26cf9f7c4e351b496241fdeBrian Carlstromimport java.security.spec.PKCS8EncodedKeySpec; 156e736056d64d0e33b26cf9f7c4e351b496241fdeBrian Carlstromimport java.security.spec.X509EncodedKeySpec; 166e736056d64d0e33b26cf9f7c4e351b496241fdeBrian Carlstrom 176e736056d64d0e33b26cf9f7c4e351b496241fdeBrian Carlstromimport javax.crypto.BadPaddingException; 186e736056d64d0e33b26cf9f7c4e351b496241fdeBrian Carlstromimport javax.crypto.Cipher; 196e736056d64d0e33b26cf9f7c4e351b496241fdeBrian Carlstromimport javax.crypto.CipherSpi; 206e736056d64d0e33b26cf9f7c4e351b496241fdeBrian Carlstromimport javax.crypto.IllegalBlockSizeException; 216e736056d64d0e33b26cf9f7c4e351b496241fdeBrian Carlstromimport javax.crypto.NoSuchPaddingException; 226e736056d64d0e33b26cf9f7c4e351b496241fdeBrian Carlstromimport javax.crypto.ShortBufferException; 236e736056d64d0e33b26cf9f7c4e351b496241fdeBrian Carlstromimport javax.crypto.spec.IvParameterSpec; 246e736056d64d0e33b26cf9f7c4e351b496241fdeBrian Carlstromimport javax.crypto.spec.PBEParameterSpec; 256e736056d64d0e33b26cf9f7c4e351b496241fdeBrian Carlstrom// BEGIN android-removed 266e736056d64d0e33b26cf9f7c4e351b496241fdeBrian Carlstrom// import javax.crypto.spec.RC2ParameterSpec; 276e736056d64d0e33b26cf9f7c4e351b496241fdeBrian Carlstrom// import javax.crypto.spec.RC5ParameterSpec; 286e736056d64d0e33b26cf9f7c4e351b496241fdeBrian Carlstrom// END android-removed 296e736056d64d0e33b26cf9f7c4e351b496241fdeBrian Carlstromimport javax.crypto.spec.SecretKeySpec; 306e736056d64d0e33b26cf9f7c4e351b496241fdeBrian Carlstrom 31b61a96e7ef1a78acf013bbf08fe537e5b5f129caPeter Hallamimport org.bouncycastle.asn1.pkcs.PrivateKeyInfo; 32b61a96e7ef1a78acf013bbf08fe537e5b5f129caPeter Hallamimport org.bouncycastle.crypto.CipherParameters; 33b61a96e7ef1a78acf013bbf08fe537e5b5f129caPeter Hallamimport org.bouncycastle.crypto.InvalidCipherTextException; 34b61a96e7ef1a78acf013bbf08fe537e5b5f129caPeter Hallamimport org.bouncycastle.crypto.Wrapper; 35b61a96e7ef1a78acf013bbf08fe537e5b5f129caPeter Hallamimport org.bouncycastle.crypto.params.KeyParameter; 36b61a96e7ef1a78acf013bbf08fe537e5b5f129caPeter Hallamimport org.bouncycastle.crypto.params.ParametersWithIV; 374c111300c39cb2e27f07fc2ae3b00e23ed4443b2Brian Carlstromimport org.bouncycastle.jce.provider.BouncyCastleProvider; 38b61a96e7ef1a78acf013bbf08fe537e5b5f129caPeter Hallam 394c111300c39cb2e27f07fc2ae3b00e23ed4443b2Brian Carlstrompublic abstract class BaseWrapCipher 404c111300c39cb2e27f07fc2ae3b00e23ed4443b2Brian Carlstrom extends CipherSpi 41b61a96e7ef1a78acf013bbf08fe537e5b5f129caPeter Hallam implements PBE 42b61a96e7ef1a78acf013bbf08fe537e5b5f129caPeter Hallam{ 43b61a96e7ef1a78acf013bbf08fe537e5b5f129caPeter Hallam // 44b61a96e7ef1a78acf013bbf08fe537e5b5f129caPeter Hallam // specs we can handle. 45b61a96e7ef1a78acf013bbf08fe537e5b5f129caPeter Hallam // 46b61a96e7ef1a78acf013bbf08fe537e5b5f129caPeter Hallam private Class[] availableSpecs = 47b61a96e7ef1a78acf013bbf08fe537e5b5f129caPeter Hallam { 48b61a96e7ef1a78acf013bbf08fe537e5b5f129caPeter Hallam IvParameterSpec.class, 49b61a96e7ef1a78acf013bbf08fe537e5b5f129caPeter Hallam PBEParameterSpec.class, 50c37f4a04ef89e73a39a59f3c5a179af8c8ab5974Brian Carlstrom // BEGIN android-removed 51c37f4a04ef89e73a39a59f3c5a179af8c8ab5974Brian Carlstrom // RC2ParameterSpec.class, 520d31ca0f54efe12f12049174bfa9403961654a92Brian Carlstrom // RC5ParameterSpec.class 53c37f4a04ef89e73a39a59f3c5a179af8c8ab5974Brian Carlstrom // END android-removed 54b61a96e7ef1a78acf013bbf08fe537e5b5f129caPeter Hallam }; 55b61a96e7ef1a78acf013bbf08fe537e5b5f129caPeter Hallam 56b61a96e7ef1a78acf013bbf08fe537e5b5f129caPeter Hallam protected int pbeType = PKCS12; 57b61a96e7ef1a78acf013bbf08fe537e5b5f129caPeter Hallam protected int pbeHash = SHA1; 58b61a96e7ef1a78acf013bbf08fe537e5b5f129caPeter Hallam protected int pbeKeySize; 59b61a96e7ef1a78acf013bbf08fe537e5b5f129caPeter Hallam protected int pbeIvSize; 60b61a96e7ef1a78acf013bbf08fe537e5b5f129caPeter Hallam 61b61a96e7ef1a78acf013bbf08fe537e5b5f129caPeter Hallam protected AlgorithmParameters engineParams = null; 62b61a96e7ef1a78acf013bbf08fe537e5b5f129caPeter Hallam 63c37f4a04ef89e73a39a59f3c5a179af8c8ab5974Brian Carlstrom protected Wrapper wrapEngine = null; 64c37f4a04ef89e73a39a59f3c5a179af8c8ab5974Brian Carlstrom 65c37f4a04ef89e73a39a59f3c5a179af8c8ab5974Brian Carlstrom private int ivSize; 66c37f4a04ef89e73a39a59f3c5a179af8c8ab5974Brian Carlstrom private byte[] iv; 67b61a96e7ef1a78acf013bbf08fe537e5b5f129caPeter Hallam 684c111300c39cb2e27f07fc2ae3b00e23ed4443b2Brian Carlstrom protected BaseWrapCipher() 69b61a96e7ef1a78acf013bbf08fe537e5b5f129caPeter Hallam { 70b61a96e7ef1a78acf013bbf08fe537e5b5f129caPeter Hallam } 71b61a96e7ef1a78acf013bbf08fe537e5b5f129caPeter Hallam 724c111300c39cb2e27f07fc2ae3b00e23ed4443b2Brian Carlstrom protected BaseWrapCipher( 73b61a96e7ef1a78acf013bbf08fe537e5b5f129caPeter Hallam Wrapper wrapEngine) 74b61a96e7ef1a78acf013bbf08fe537e5b5f129caPeter Hallam { 75c37f4a04ef89e73a39a59f3c5a179af8c8ab5974Brian Carlstrom this(wrapEngine, 0); 76c37f4a04ef89e73a39a59f3c5a179af8c8ab5974Brian Carlstrom } 77c37f4a04ef89e73a39a59f3c5a179af8c8ab5974Brian Carlstrom 784c111300c39cb2e27f07fc2ae3b00e23ed4443b2Brian Carlstrom protected BaseWrapCipher( 79c37f4a04ef89e73a39a59f3c5a179af8c8ab5974Brian Carlstrom Wrapper wrapEngine, 804c111300c39cb2e27f07fc2ae3b00e23ed4443b2Brian Carlstrom int ivSize) 81c37f4a04ef89e73a39a59f3c5a179af8c8ab5974Brian Carlstrom { 82b61a96e7ef1a78acf013bbf08fe537e5b5f129caPeter Hallam this.wrapEngine = wrapEngine; 83c37f4a04ef89e73a39a59f3c5a179af8c8ab5974Brian Carlstrom this.ivSize = ivSize; 84b61a96e7ef1a78acf013bbf08fe537e5b5f129caPeter Hallam } 85b61a96e7ef1a78acf013bbf08fe537e5b5f129caPeter Hallam 86b61a96e7ef1a78acf013bbf08fe537e5b5f129caPeter Hallam protected int engineGetBlockSize() 87b61a96e7ef1a78acf013bbf08fe537e5b5f129caPeter Hallam { 88b61a96e7ef1a78acf013bbf08fe537e5b5f129caPeter Hallam return 0; 89b61a96e7ef1a78acf013bbf08fe537e5b5f129caPeter Hallam } 90b61a96e7ef1a78acf013bbf08fe537e5b5f129caPeter Hallam 91b61a96e7ef1a78acf013bbf08fe537e5b5f129caPeter Hallam protected byte[] engineGetIV() 92b61a96e7ef1a78acf013bbf08fe537e5b5f129caPeter Hallam { 93c37f4a04ef89e73a39a59f3c5a179af8c8ab5974Brian Carlstrom return (byte[])iv.clone(); 94b61a96e7ef1a78acf013bbf08fe537e5b5f129caPeter Hallam } 95b61a96e7ef1a78acf013bbf08fe537e5b5f129caPeter Hallam 96b61a96e7ef1a78acf013bbf08fe537e5b5f129caPeter Hallam protected int engineGetKeySize( 97b61a96e7ef1a78acf013bbf08fe537e5b5f129caPeter Hallam Key key) 98b61a96e7ef1a78acf013bbf08fe537e5b5f129caPeter Hallam { 99b61a96e7ef1a78acf013bbf08fe537e5b5f129caPeter Hallam return key.getEncoded().length; 100b61a96e7ef1a78acf013bbf08fe537e5b5f129caPeter Hallam } 101b61a96e7ef1a78acf013bbf08fe537e5b5f129caPeter Hallam 102b61a96e7ef1a78acf013bbf08fe537e5b5f129caPeter Hallam protected int engineGetOutputSize( 103b61a96e7ef1a78acf013bbf08fe537e5b5f129caPeter Hallam int inputLen) 104b61a96e7ef1a78acf013bbf08fe537e5b5f129caPeter Hallam { 105b61a96e7ef1a78acf013bbf08fe537e5b5f129caPeter Hallam return -1; 106b61a96e7ef1a78acf013bbf08fe537e5b5f129caPeter Hallam } 107b61a96e7ef1a78acf013bbf08fe537e5b5f129caPeter Hallam 108b61a96e7ef1a78acf013bbf08fe537e5b5f129caPeter Hallam protected AlgorithmParameters engineGetParameters() 109b61a96e7ef1a78acf013bbf08fe537e5b5f129caPeter Hallam { 110b61a96e7ef1a78acf013bbf08fe537e5b5f129caPeter Hallam return null; 111b61a96e7ef1a78acf013bbf08fe537e5b5f129caPeter Hallam } 112b61a96e7ef1a78acf013bbf08fe537e5b5f129caPeter Hallam 113b61a96e7ef1a78acf013bbf08fe537e5b5f129caPeter Hallam protected void engineSetMode( 114b61a96e7ef1a78acf013bbf08fe537e5b5f129caPeter Hallam String mode) 115b61a96e7ef1a78acf013bbf08fe537e5b5f129caPeter Hallam throws NoSuchAlgorithmException 116b61a96e7ef1a78acf013bbf08fe537e5b5f129caPeter Hallam { 117b61a96e7ef1a78acf013bbf08fe537e5b5f129caPeter Hallam throw new NoSuchAlgorithmException("can't support mode " + mode); 118b61a96e7ef1a78acf013bbf08fe537e5b5f129caPeter Hallam } 119b61a96e7ef1a78acf013bbf08fe537e5b5f129caPeter Hallam 120b61a96e7ef1a78acf013bbf08fe537e5b5f129caPeter Hallam protected void engineSetPadding( 121b61a96e7ef1a78acf013bbf08fe537e5b5f129caPeter Hallam String padding) 122b61a96e7ef1a78acf013bbf08fe537e5b5f129caPeter Hallam throws NoSuchPaddingException 123b61a96e7ef1a78acf013bbf08fe537e5b5f129caPeter Hallam { 124b61a96e7ef1a78acf013bbf08fe537e5b5f129caPeter Hallam throw new NoSuchPaddingException("Padding " + padding + " unknown."); 125b61a96e7ef1a78acf013bbf08fe537e5b5f129caPeter Hallam } 126b61a96e7ef1a78acf013bbf08fe537e5b5f129caPeter Hallam 127b61a96e7ef1a78acf013bbf08fe537e5b5f129caPeter Hallam protected void engineInit( 128b61a96e7ef1a78acf013bbf08fe537e5b5f129caPeter Hallam int opmode, 129b61a96e7ef1a78acf013bbf08fe537e5b5f129caPeter Hallam Key key, 130b61a96e7ef1a78acf013bbf08fe537e5b5f129caPeter Hallam AlgorithmParameterSpec params, 131b61a96e7ef1a78acf013bbf08fe537e5b5f129caPeter Hallam SecureRandom random) 132b61a96e7ef1a78acf013bbf08fe537e5b5f129caPeter Hallam throws InvalidKeyException, InvalidAlgorithmParameterException 133b61a96e7ef1a78acf013bbf08fe537e5b5f129caPeter Hallam { 134b61a96e7ef1a78acf013bbf08fe537e5b5f129caPeter Hallam CipherParameters param; 135b61a96e7ef1a78acf013bbf08fe537e5b5f129caPeter Hallam 1364c111300c39cb2e27f07fc2ae3b00e23ed4443b2Brian Carlstrom if (key instanceof BCPBEKey) 137b61a96e7ef1a78acf013bbf08fe537e5b5f129caPeter Hallam { 1384c111300c39cb2e27f07fc2ae3b00e23ed4443b2Brian Carlstrom BCPBEKey k = (BCPBEKey)key; 1394c111300c39cb2e27f07fc2ae3b00e23ed4443b2Brian Carlstrom 140b61a96e7ef1a78acf013bbf08fe537e5b5f129caPeter Hallam if (params instanceof PBEParameterSpec) 141b61a96e7ef1a78acf013bbf08fe537e5b5f129caPeter Hallam { 142b61a96e7ef1a78acf013bbf08fe537e5b5f129caPeter Hallam param = PBE.Util.makePBEParameters(k, params, wrapEngine.getAlgorithmName()); 143b61a96e7ef1a78acf013bbf08fe537e5b5f129caPeter Hallam } 144b61a96e7ef1a78acf013bbf08fe537e5b5f129caPeter Hallam else if (k.getParam() != null) 145b61a96e7ef1a78acf013bbf08fe537e5b5f129caPeter Hallam { 146b61a96e7ef1a78acf013bbf08fe537e5b5f129caPeter Hallam param = k.getParam(); 147b61a96e7ef1a78acf013bbf08fe537e5b5f129caPeter Hallam } 148b61a96e7ef1a78acf013bbf08fe537e5b5f129caPeter Hallam else 149b61a96e7ef1a78acf013bbf08fe537e5b5f129caPeter Hallam { 150b61a96e7ef1a78acf013bbf08fe537e5b5f129caPeter Hallam throw new InvalidAlgorithmParameterException("PBE requires PBE parameters to be set."); 151b61a96e7ef1a78acf013bbf08fe537e5b5f129caPeter Hallam } 152b61a96e7ef1a78acf013bbf08fe537e5b5f129caPeter Hallam } 153b61a96e7ef1a78acf013bbf08fe537e5b5f129caPeter Hallam else 154b61a96e7ef1a78acf013bbf08fe537e5b5f129caPeter Hallam { 155b61a96e7ef1a78acf013bbf08fe537e5b5f129caPeter Hallam param = new KeyParameter(key.getEncoded()); 156b61a96e7ef1a78acf013bbf08fe537e5b5f129caPeter Hallam } 157b61a96e7ef1a78acf013bbf08fe537e5b5f129caPeter Hallam 1584c111300c39cb2e27f07fc2ae3b00e23ed4443b2Brian Carlstrom if (params instanceof IvParameterSpec) 159b61a96e7ef1a78acf013bbf08fe537e5b5f129caPeter Hallam { 160b61a96e7ef1a78acf013bbf08fe537e5b5f129caPeter Hallam IvParameterSpec iv = (IvParameterSpec) params; 161c37f4a04ef89e73a39a59f3c5a179af8c8ab5974Brian Carlstrom param = new ParametersWithIV(param, iv.getIV()); 162c37f4a04ef89e73a39a59f3c5a179af8c8ab5974Brian Carlstrom } 163c37f4a04ef89e73a39a59f3c5a179af8c8ab5974Brian Carlstrom 164c37f4a04ef89e73a39a59f3c5a179af8c8ab5974Brian Carlstrom if (param instanceof KeyParameter && ivSize != 0) 165c37f4a04ef89e73a39a59f3c5a179af8c8ab5974Brian Carlstrom { 166c37f4a04ef89e73a39a59f3c5a179af8c8ab5974Brian Carlstrom iv = new byte[ivSize]; 167c37f4a04ef89e73a39a59f3c5a179af8c8ab5974Brian Carlstrom random.nextBytes(iv); 168c37f4a04ef89e73a39a59f3c5a179af8c8ab5974Brian Carlstrom param = new ParametersWithIV(param, iv); 169b61a96e7ef1a78acf013bbf08fe537e5b5f129caPeter Hallam } 170b61a96e7ef1a78acf013bbf08fe537e5b5f129caPeter Hallam 171b61a96e7ef1a78acf013bbf08fe537e5b5f129caPeter Hallam switch (opmode) 172b61a96e7ef1a78acf013bbf08fe537e5b5f129caPeter Hallam { 173b61a96e7ef1a78acf013bbf08fe537e5b5f129caPeter Hallam case Cipher.WRAP_MODE: 174b61a96e7ef1a78acf013bbf08fe537e5b5f129caPeter Hallam wrapEngine.init(true, param); 175b61a96e7ef1a78acf013bbf08fe537e5b5f129caPeter Hallam break; 176b61a96e7ef1a78acf013bbf08fe537e5b5f129caPeter Hallam case Cipher.UNWRAP_MODE: 177b61a96e7ef1a78acf013bbf08fe537e5b5f129caPeter Hallam wrapEngine.init(false, param); 178b61a96e7ef1a78acf013bbf08fe537e5b5f129caPeter Hallam break; 179b61a96e7ef1a78acf013bbf08fe537e5b5f129caPeter Hallam case Cipher.ENCRYPT_MODE: 180b61a96e7ef1a78acf013bbf08fe537e5b5f129caPeter Hallam case Cipher.DECRYPT_MODE: 181b61a96e7ef1a78acf013bbf08fe537e5b5f129caPeter Hallam throw new IllegalArgumentException("engine only valid for wrapping"); 182b61a96e7ef1a78acf013bbf08fe537e5b5f129caPeter Hallam default: 183b61a96e7ef1a78acf013bbf08fe537e5b5f129caPeter Hallam System.out.println("eeek!"); 184b61a96e7ef1a78acf013bbf08fe537e5b5f129caPeter Hallam } 185b61a96e7ef1a78acf013bbf08fe537e5b5f129caPeter Hallam } 186b61a96e7ef1a78acf013bbf08fe537e5b5f129caPeter Hallam 187b61a96e7ef1a78acf013bbf08fe537e5b5f129caPeter Hallam protected void engineInit( 188b61a96e7ef1a78acf013bbf08fe537e5b5f129caPeter Hallam int opmode, 189b61a96e7ef1a78acf013bbf08fe537e5b5f129caPeter Hallam Key key, 190b61a96e7ef1a78acf013bbf08fe537e5b5f129caPeter Hallam AlgorithmParameters params, 191b61a96e7ef1a78acf013bbf08fe537e5b5f129caPeter Hallam SecureRandom random) 192b61a96e7ef1a78acf013bbf08fe537e5b5f129caPeter Hallam throws InvalidKeyException, InvalidAlgorithmParameterException 193b61a96e7ef1a78acf013bbf08fe537e5b5f129caPeter Hallam { 194b61a96e7ef1a78acf013bbf08fe537e5b5f129caPeter Hallam AlgorithmParameterSpec paramSpec = null; 195b61a96e7ef1a78acf013bbf08fe537e5b5f129caPeter Hallam 196b61a96e7ef1a78acf013bbf08fe537e5b5f129caPeter Hallam if (params != null) 197b61a96e7ef1a78acf013bbf08fe537e5b5f129caPeter Hallam { 198b61a96e7ef1a78acf013bbf08fe537e5b5f129caPeter Hallam for (int i = 0; i != availableSpecs.length; i++) 199b61a96e7ef1a78acf013bbf08fe537e5b5f129caPeter Hallam { 200b61a96e7ef1a78acf013bbf08fe537e5b5f129caPeter Hallam try 201b61a96e7ef1a78acf013bbf08fe537e5b5f129caPeter Hallam { 202b61a96e7ef1a78acf013bbf08fe537e5b5f129caPeter Hallam paramSpec = params.getParameterSpec(availableSpecs[i]); 203b61a96e7ef1a78acf013bbf08fe537e5b5f129caPeter Hallam break; 204b61a96e7ef1a78acf013bbf08fe537e5b5f129caPeter Hallam } 205b61a96e7ef1a78acf013bbf08fe537e5b5f129caPeter Hallam catch (Exception e) 206b61a96e7ef1a78acf013bbf08fe537e5b5f129caPeter Hallam { 207c37f4a04ef89e73a39a59f3c5a179af8c8ab5974Brian Carlstrom // try next spec 208b61a96e7ef1a78acf013bbf08fe537e5b5f129caPeter Hallam } 209b61a96e7ef1a78acf013bbf08fe537e5b5f129caPeter Hallam } 210b61a96e7ef1a78acf013bbf08fe537e5b5f129caPeter Hallam 211b61a96e7ef1a78acf013bbf08fe537e5b5f129caPeter Hallam if (paramSpec == null) 212b61a96e7ef1a78acf013bbf08fe537e5b5f129caPeter Hallam { 213b61a96e7ef1a78acf013bbf08fe537e5b5f129caPeter Hallam throw new InvalidAlgorithmParameterException("can't handle parameter " + params.toString()); 214b61a96e7ef1a78acf013bbf08fe537e5b5f129caPeter Hallam } 215b61a96e7ef1a78acf013bbf08fe537e5b5f129caPeter Hallam } 216b61a96e7ef1a78acf013bbf08fe537e5b5f129caPeter Hallam 217b61a96e7ef1a78acf013bbf08fe537e5b5f129caPeter Hallam engineParams = params; 218b61a96e7ef1a78acf013bbf08fe537e5b5f129caPeter Hallam engineInit(opmode, key, paramSpec, random); 219b61a96e7ef1a78acf013bbf08fe537e5b5f129caPeter Hallam } 220b61a96e7ef1a78acf013bbf08fe537e5b5f129caPeter Hallam 221b61a96e7ef1a78acf013bbf08fe537e5b5f129caPeter Hallam protected void engineInit( 222b61a96e7ef1a78acf013bbf08fe537e5b5f129caPeter Hallam int opmode, 223b61a96e7ef1a78acf013bbf08fe537e5b5f129caPeter Hallam Key key, 224b61a96e7ef1a78acf013bbf08fe537e5b5f129caPeter Hallam SecureRandom random) 225b61a96e7ef1a78acf013bbf08fe537e5b5f129caPeter Hallam throws InvalidKeyException 226b61a96e7ef1a78acf013bbf08fe537e5b5f129caPeter Hallam { 227b61a96e7ef1a78acf013bbf08fe537e5b5f129caPeter Hallam try 228b61a96e7ef1a78acf013bbf08fe537e5b5f129caPeter Hallam { 229b61a96e7ef1a78acf013bbf08fe537e5b5f129caPeter Hallam engineInit(opmode, key, (AlgorithmParameterSpec)null, random); 230b61a96e7ef1a78acf013bbf08fe537e5b5f129caPeter Hallam } 231b61a96e7ef1a78acf013bbf08fe537e5b5f129caPeter Hallam catch (InvalidAlgorithmParameterException e) 232b61a96e7ef1a78acf013bbf08fe537e5b5f129caPeter Hallam { 233b61a96e7ef1a78acf013bbf08fe537e5b5f129caPeter Hallam throw new IllegalArgumentException(e.getMessage()); 234b61a96e7ef1a78acf013bbf08fe537e5b5f129caPeter Hallam } 235b61a96e7ef1a78acf013bbf08fe537e5b5f129caPeter Hallam } 236b61a96e7ef1a78acf013bbf08fe537e5b5f129caPeter Hallam 237b61a96e7ef1a78acf013bbf08fe537e5b5f129caPeter Hallam protected byte[] engineUpdate( 238b61a96e7ef1a78acf013bbf08fe537e5b5f129caPeter Hallam byte[] input, 239b61a96e7ef1a78acf013bbf08fe537e5b5f129caPeter Hallam int inputOffset, 240b61a96e7ef1a78acf013bbf08fe537e5b5f129caPeter Hallam int inputLen) 241b61a96e7ef1a78acf013bbf08fe537e5b5f129caPeter Hallam { 242b61a96e7ef1a78acf013bbf08fe537e5b5f129caPeter Hallam throw new RuntimeException("not supported for wrapping"); 243b61a96e7ef1a78acf013bbf08fe537e5b5f129caPeter Hallam } 244b61a96e7ef1a78acf013bbf08fe537e5b5f129caPeter Hallam 245b61a96e7ef1a78acf013bbf08fe537e5b5f129caPeter Hallam protected int engineUpdate( 246b61a96e7ef1a78acf013bbf08fe537e5b5f129caPeter Hallam byte[] input, 247b61a96e7ef1a78acf013bbf08fe537e5b5f129caPeter Hallam int inputOffset, 248b61a96e7ef1a78acf013bbf08fe537e5b5f129caPeter Hallam int inputLen, 249b61a96e7ef1a78acf013bbf08fe537e5b5f129caPeter Hallam byte[] output, 250b61a96e7ef1a78acf013bbf08fe537e5b5f129caPeter Hallam int outputOffset) 251b61a96e7ef1a78acf013bbf08fe537e5b5f129caPeter Hallam throws ShortBufferException 252b61a96e7ef1a78acf013bbf08fe537e5b5f129caPeter Hallam { 253b61a96e7ef1a78acf013bbf08fe537e5b5f129caPeter Hallam throw new RuntimeException("not supported for wrapping"); 254b61a96e7ef1a78acf013bbf08fe537e5b5f129caPeter Hallam } 255b61a96e7ef1a78acf013bbf08fe537e5b5f129caPeter Hallam 256b61a96e7ef1a78acf013bbf08fe537e5b5f129caPeter Hallam protected byte[] engineDoFinal( 257b61a96e7ef1a78acf013bbf08fe537e5b5f129caPeter Hallam byte[] input, 258b61a96e7ef1a78acf013bbf08fe537e5b5f129caPeter Hallam int inputOffset, 259b61a96e7ef1a78acf013bbf08fe537e5b5f129caPeter Hallam int inputLen) 260b61a96e7ef1a78acf013bbf08fe537e5b5f129caPeter Hallam throws IllegalBlockSizeException, BadPaddingException 261b61a96e7ef1a78acf013bbf08fe537e5b5f129caPeter Hallam { 262b61a96e7ef1a78acf013bbf08fe537e5b5f129caPeter Hallam return null; 263b61a96e7ef1a78acf013bbf08fe537e5b5f129caPeter Hallam } 264b61a96e7ef1a78acf013bbf08fe537e5b5f129caPeter Hallam 265b61a96e7ef1a78acf013bbf08fe537e5b5f129caPeter Hallam // BEGIN android-changed 266b61a96e7ef1a78acf013bbf08fe537e5b5f129caPeter Hallam // added ShortBufferException to throws statement 267b61a96e7ef1a78acf013bbf08fe537e5b5f129caPeter Hallam protected int engineDoFinal( 268b61a96e7ef1a78acf013bbf08fe537e5b5f129caPeter Hallam byte[] input, 269b61a96e7ef1a78acf013bbf08fe537e5b5f129caPeter Hallam int inputOffset, 270b61a96e7ef1a78acf013bbf08fe537e5b5f129caPeter Hallam int inputLen, 271b61a96e7ef1a78acf013bbf08fe537e5b5f129caPeter Hallam byte[] output, 272b61a96e7ef1a78acf013bbf08fe537e5b5f129caPeter Hallam int outputOffset) 273b61a96e7ef1a78acf013bbf08fe537e5b5f129caPeter Hallam throws IllegalBlockSizeException, BadPaddingException, ShortBufferException 274b61a96e7ef1a78acf013bbf08fe537e5b5f129caPeter Hallam { 275b61a96e7ef1a78acf013bbf08fe537e5b5f129caPeter Hallam return 0; 276b61a96e7ef1a78acf013bbf08fe537e5b5f129caPeter Hallam } 277b61a96e7ef1a78acf013bbf08fe537e5b5f129caPeter Hallam // END android-changed 278b61a96e7ef1a78acf013bbf08fe537e5b5f129caPeter Hallam 279b61a96e7ef1a78acf013bbf08fe537e5b5f129caPeter Hallam protected byte[] engineWrap( 280b61a96e7ef1a78acf013bbf08fe537e5b5f129caPeter Hallam Key key) 2814c111300c39cb2e27f07fc2ae3b00e23ed4443b2Brian Carlstrom throws IllegalBlockSizeException, InvalidKeyException 282b61a96e7ef1a78acf013bbf08fe537e5b5f129caPeter Hallam { 283b61a96e7ef1a78acf013bbf08fe537e5b5f129caPeter Hallam byte[] encoded = key.getEncoded(); 284b61a96e7ef1a78acf013bbf08fe537e5b5f129caPeter Hallam if (encoded == null) 285b61a96e7ef1a78acf013bbf08fe537e5b5f129caPeter Hallam { 286b61a96e7ef1a78acf013bbf08fe537e5b5f129caPeter Hallam throw new InvalidKeyException("Cannot wrap key, null encoding."); 287b61a96e7ef1a78acf013bbf08fe537e5b5f129caPeter Hallam } 288b61a96e7ef1a78acf013bbf08fe537e5b5f129caPeter Hallam 289b61a96e7ef1a78acf013bbf08fe537e5b5f129caPeter Hallam try 290b61a96e7ef1a78acf013bbf08fe537e5b5f129caPeter Hallam { 291b61a96e7ef1a78acf013bbf08fe537e5b5f129caPeter Hallam if (wrapEngine == null) 292b61a96e7ef1a78acf013bbf08fe537e5b5f129caPeter Hallam { 293b61a96e7ef1a78acf013bbf08fe537e5b5f129caPeter Hallam return engineDoFinal(encoded, 0, encoded.length); 294b61a96e7ef1a78acf013bbf08fe537e5b5f129caPeter Hallam } 295b61a96e7ef1a78acf013bbf08fe537e5b5f129caPeter Hallam else 296b61a96e7ef1a78acf013bbf08fe537e5b5f129caPeter Hallam { 297b61a96e7ef1a78acf013bbf08fe537e5b5f129caPeter Hallam return wrapEngine.wrap(encoded, 0, encoded.length); 298b61a96e7ef1a78acf013bbf08fe537e5b5f129caPeter Hallam } 299b61a96e7ef1a78acf013bbf08fe537e5b5f129caPeter Hallam } 300b61a96e7ef1a78acf013bbf08fe537e5b5f129caPeter Hallam catch (BadPaddingException e) 301b61a96e7ef1a78acf013bbf08fe537e5b5f129caPeter Hallam { 302b61a96e7ef1a78acf013bbf08fe537e5b5f129caPeter Hallam throw new IllegalBlockSizeException(e.getMessage()); 303b61a96e7ef1a78acf013bbf08fe537e5b5f129caPeter Hallam } 304b61a96e7ef1a78acf013bbf08fe537e5b5f129caPeter Hallam } 305b61a96e7ef1a78acf013bbf08fe537e5b5f129caPeter Hallam 306b61a96e7ef1a78acf013bbf08fe537e5b5f129caPeter Hallam protected Key engineUnwrap( 307b61a96e7ef1a78acf013bbf08fe537e5b5f129caPeter Hallam byte[] wrappedKey, 308b61a96e7ef1a78acf013bbf08fe537e5b5f129caPeter Hallam String wrappedKeyAlgorithm, 309b61a96e7ef1a78acf013bbf08fe537e5b5f129caPeter Hallam int wrappedKeyType) 310c37f4a04ef89e73a39a59f3c5a179af8c8ab5974Brian Carlstrom // BEGIN android-removed 311c37f4a04ef89e73a39a59f3c5a179af8c8ab5974Brian Carlstrom // throws InvalidKeyException 312c37f4a04ef89e73a39a59f3c5a179af8c8ab5974Brian Carlstrom // END android-removed 313c37f4a04ef89e73a39a59f3c5a179af8c8ab5974Brian Carlstrom // BEGIN android-added 314b61a96e7ef1a78acf013bbf08fe537e5b5f129caPeter Hallam throws InvalidKeyException, NoSuchAlgorithmException 315c37f4a04ef89e73a39a59f3c5a179af8c8ab5974Brian Carlstrom // END android-added 316b61a96e7ef1a78acf013bbf08fe537e5b5f129caPeter Hallam { 317c37f4a04ef89e73a39a59f3c5a179af8c8ab5974Brian Carlstrom byte[] encoded; 318b61a96e7ef1a78acf013bbf08fe537e5b5f129caPeter Hallam try 319b61a96e7ef1a78acf013bbf08fe537e5b5f129caPeter Hallam { 320b61a96e7ef1a78acf013bbf08fe537e5b5f129caPeter Hallam if (wrapEngine == null) 321b61a96e7ef1a78acf013bbf08fe537e5b5f129caPeter Hallam { 322b61a96e7ef1a78acf013bbf08fe537e5b5f129caPeter Hallam encoded = engineDoFinal(wrappedKey, 0, wrappedKey.length); 323b61a96e7ef1a78acf013bbf08fe537e5b5f129caPeter Hallam } 324b61a96e7ef1a78acf013bbf08fe537e5b5f129caPeter Hallam else 325b61a96e7ef1a78acf013bbf08fe537e5b5f129caPeter Hallam { 326b61a96e7ef1a78acf013bbf08fe537e5b5f129caPeter Hallam encoded = wrapEngine.unwrap(wrappedKey, 0, wrappedKey.length); 327b61a96e7ef1a78acf013bbf08fe537e5b5f129caPeter Hallam } 328b61a96e7ef1a78acf013bbf08fe537e5b5f129caPeter Hallam } 329b61a96e7ef1a78acf013bbf08fe537e5b5f129caPeter Hallam catch (InvalidCipherTextException e) 330b61a96e7ef1a78acf013bbf08fe537e5b5f129caPeter Hallam { 331b61a96e7ef1a78acf013bbf08fe537e5b5f129caPeter Hallam throw new InvalidKeyException(e.getMessage()); 332b61a96e7ef1a78acf013bbf08fe537e5b5f129caPeter Hallam } 333b61a96e7ef1a78acf013bbf08fe537e5b5f129caPeter Hallam catch (BadPaddingException e) 334b61a96e7ef1a78acf013bbf08fe537e5b5f129caPeter Hallam { 335b61a96e7ef1a78acf013bbf08fe537e5b5f129caPeter Hallam throw new InvalidKeyException(e.getMessage()); 336b61a96e7ef1a78acf013bbf08fe537e5b5f129caPeter Hallam } 337b61a96e7ef1a78acf013bbf08fe537e5b5f129caPeter Hallam catch (IllegalBlockSizeException e2) 338b61a96e7ef1a78acf013bbf08fe537e5b5f129caPeter Hallam { 339b61a96e7ef1a78acf013bbf08fe537e5b5f129caPeter Hallam throw new InvalidKeyException(e2.getMessage()); 340b61a96e7ef1a78acf013bbf08fe537e5b5f129caPeter Hallam } 341b61a96e7ef1a78acf013bbf08fe537e5b5f129caPeter Hallam 342b61a96e7ef1a78acf013bbf08fe537e5b5f129caPeter Hallam if (wrappedKeyType == Cipher.SECRET_KEY) 343b61a96e7ef1a78acf013bbf08fe537e5b5f129caPeter Hallam { 344b61a96e7ef1a78acf013bbf08fe537e5b5f129caPeter Hallam return new SecretKeySpec(encoded, wrappedKeyAlgorithm); 345b61a96e7ef1a78acf013bbf08fe537e5b5f129caPeter Hallam } 346b61a96e7ef1a78acf013bbf08fe537e5b5f129caPeter Hallam else if (wrappedKeyAlgorithm.equals("") && wrappedKeyType == Cipher.PRIVATE_KEY) 347b61a96e7ef1a78acf013bbf08fe537e5b5f129caPeter Hallam { 348b61a96e7ef1a78acf013bbf08fe537e5b5f129caPeter Hallam /* 3494c111300c39cb2e27f07fc2ae3b00e23ed4443b2Brian Carlstrom * The caller doesn't know the algorithm as it is part of 3504c111300c39cb2e27f07fc2ae3b00e23ed4443b2Brian Carlstrom * the encrypted data. 3514c111300c39cb2e27f07fc2ae3b00e23ed4443b2Brian Carlstrom */ 352b61a96e7ef1a78acf013bbf08fe537e5b5f129caPeter Hallam try 353b61a96e7ef1a78acf013bbf08fe537e5b5f129caPeter Hallam { 3544c111300c39cb2e27f07fc2ae3b00e23ed4443b2Brian Carlstrom PrivateKeyInfo in = PrivateKeyInfo.getInstance(encoded); 355b61a96e7ef1a78acf013bbf08fe537e5b5f129caPeter Hallam 3564c111300c39cb2e27f07fc2ae3b00e23ed4443b2Brian Carlstrom PrivateKey privKey = BouncyCastleProvider.getPrivateKey(in); 357b61a96e7ef1a78acf013bbf08fe537e5b5f129caPeter Hallam 3584c111300c39cb2e27f07fc2ae3b00e23ed4443b2Brian Carlstrom if (privKey != null) 359b61a96e7ef1a78acf013bbf08fe537e5b5f129caPeter Hallam { 3604c111300c39cb2e27f07fc2ae3b00e23ed4443b2Brian Carlstrom return privKey; 361b61a96e7ef1a78acf013bbf08fe537e5b5f129caPeter Hallam } 3624c111300c39cb2e27f07fc2ae3b00e23ed4443b2Brian Carlstrom else 363b61a96e7ef1a78acf013bbf08fe537e5b5f129caPeter Hallam { 3644c111300c39cb2e27f07fc2ae3b00e23ed4443b2Brian Carlstrom throw new InvalidKeyException("algorithm " + in.getPrivateKeyAlgorithm().getAlgorithm() + " not supported"); 365b61a96e7ef1a78acf013bbf08fe537e5b5f129caPeter Hallam } 366b61a96e7ef1a78acf013bbf08fe537e5b5f129caPeter Hallam } 367b61a96e7ef1a78acf013bbf08fe537e5b5f129caPeter Hallam catch (Exception e) 368b61a96e7ef1a78acf013bbf08fe537e5b5f129caPeter Hallam { 369b61a96e7ef1a78acf013bbf08fe537e5b5f129caPeter Hallam throw new InvalidKeyException("Invalid key encoding."); 370b61a96e7ef1a78acf013bbf08fe537e5b5f129caPeter Hallam } 371b61a96e7ef1a78acf013bbf08fe537e5b5f129caPeter Hallam } 372b61a96e7ef1a78acf013bbf08fe537e5b5f129caPeter Hallam else 373b61a96e7ef1a78acf013bbf08fe537e5b5f129caPeter Hallam { 374b61a96e7ef1a78acf013bbf08fe537e5b5f129caPeter Hallam try 375b61a96e7ef1a78acf013bbf08fe537e5b5f129caPeter Hallam { 3766e736056d64d0e33b26cf9f7c4e351b496241fdeBrian Carlstrom KeyFactory kf = KeyFactory.getInstance(wrappedKeyAlgorithm, BouncyCastleProvider.PROVIDER_NAME); 377b61a96e7ef1a78acf013bbf08fe537e5b5f129caPeter Hallam 378b61a96e7ef1a78acf013bbf08fe537e5b5f129caPeter Hallam if (wrappedKeyType == Cipher.PUBLIC_KEY) 379b61a96e7ef1a78acf013bbf08fe537e5b5f129caPeter Hallam { 380b61a96e7ef1a78acf013bbf08fe537e5b5f129caPeter Hallam return kf.generatePublic(new X509EncodedKeySpec(encoded)); 381b61a96e7ef1a78acf013bbf08fe537e5b5f129caPeter Hallam } 382b61a96e7ef1a78acf013bbf08fe537e5b5f129caPeter Hallam else if (wrappedKeyType == Cipher.PRIVATE_KEY) 383b61a96e7ef1a78acf013bbf08fe537e5b5f129caPeter Hallam { 384b61a96e7ef1a78acf013bbf08fe537e5b5f129caPeter Hallam return kf.generatePrivate(new PKCS8EncodedKeySpec(encoded)); 385b61a96e7ef1a78acf013bbf08fe537e5b5f129caPeter Hallam } 386b61a96e7ef1a78acf013bbf08fe537e5b5f129caPeter Hallam } 387b61a96e7ef1a78acf013bbf08fe537e5b5f129caPeter Hallam catch (NoSuchProviderException e) 388b61a96e7ef1a78acf013bbf08fe537e5b5f129caPeter Hallam { 389b61a96e7ef1a78acf013bbf08fe537e5b5f129caPeter Hallam throw new InvalidKeyException("Unknown key type " + e.getMessage()); 390b61a96e7ef1a78acf013bbf08fe537e5b5f129caPeter Hallam } 391b61a96e7ef1a78acf013bbf08fe537e5b5f129caPeter Hallam // BEGIN android-removed 392b61a96e7ef1a78acf013bbf08fe537e5b5f129caPeter Hallam // catch (NoSuchAlgorithmException e) 393b61a96e7ef1a78acf013bbf08fe537e5b5f129caPeter Hallam // { 394b61a96e7ef1a78acf013bbf08fe537e5b5f129caPeter Hallam // throw new InvalidKeyException("Unknown key type " + e.getMessage()); 395b61a96e7ef1a78acf013bbf08fe537e5b5f129caPeter Hallam // } 396b61a96e7ef1a78acf013bbf08fe537e5b5f129caPeter Hallam // END android-removed 397b61a96e7ef1a78acf013bbf08fe537e5b5f129caPeter Hallam catch (InvalidKeySpecException e2) 398b61a96e7ef1a78acf013bbf08fe537e5b5f129caPeter Hallam { 399b61a96e7ef1a78acf013bbf08fe537e5b5f129caPeter Hallam throw new InvalidKeyException("Unknown key type " + e2.getMessage()); 400b61a96e7ef1a78acf013bbf08fe537e5b5f129caPeter Hallam } 401b61a96e7ef1a78acf013bbf08fe537e5b5f129caPeter Hallam 402b61a96e7ef1a78acf013bbf08fe537e5b5f129caPeter Hallam throw new InvalidKeyException("Unknown key type " + wrappedKeyType); 403b61a96e7ef1a78acf013bbf08fe537e5b5f129caPeter Hallam } 404b61a96e7ef1a78acf013bbf08fe537e5b5f129caPeter Hallam } 405b61a96e7ef1a78acf013bbf08fe537e5b5f129caPeter Hallam 406b61a96e7ef1a78acf013bbf08fe537e5b5f129caPeter Hallam} 407