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