1f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project/* 2f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project * Licensed to the Apache Software Foundation (ASF) under one or more 3f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project * contributor license agreements. See the NOTICE file distributed with 4f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project * this work for additional information regarding copyright ownership. 5f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project * The ASF licenses this file to You under the Apache License, Version 2.0 6f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project * (the "License"); you may not use this file except in compliance with 7f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project * the License. You may obtain a copy of the License at 8f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project * 9f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project * http://www.apache.org/licenses/LICENSE-2.0 10f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project * 11f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project * Unless required by applicable law or agreed to in writing, software 12f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project * distributed under the License is distributed on an "AS IS" BASIS, 13f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 14f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project * See the License for the specific language governing permissions and 15f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project * limitations under the License. 16f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project */ 17f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project 18f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Projectpackage javax.crypto; 19f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project 20f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Projectimport java.io.ByteArrayInputStream; 21f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Projectimport java.io.ByteArrayOutputStream; 22f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Projectimport java.io.IOException; 23f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Projectimport java.io.ObjectInputStream; 24f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Projectimport java.io.ObjectOutputStream; 25f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Projectimport java.io.Serializable; 26f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Projectimport java.security.AlgorithmParameters; 27f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Projectimport java.security.InvalidAlgorithmParameterException; 28f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Projectimport java.security.InvalidKeyException; 29f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Projectimport java.security.Key; 30f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Projectimport java.security.NoSuchAlgorithmException; 31f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Projectimport java.security.NoSuchProviderException; 32f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Projectimport javax.crypto.IllegalBlockSizeException; 33f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Projectimport javax.crypto.NoSuchPaddingException; 34f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project 35f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Projectimport org.apache.harmony.crypto.internal.nls.Messages; 36f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project 37f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project/** 38f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project * A {@code SealedObject} is a wrapper around a {@code serializable} object 39f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project * instance and encrypts it using a cryptographic cipher. 40f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project * <p> 41f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project * Since a {@code SealedObject} instance is a serializable object itself it can 42f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project * either be stored or transmitted over an insecure channel. 438207f1e8dbc63916f238f81dc46567c55090e95bJesse Wilson * <p> 44f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project * The wrapped object can later be decrypted (unsealed) using the corresponding 45f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project * key and then be deserialized to retrieve the original object.The sealed 46f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project * object itself keeps track of the cipher and corresponding parameters. 47f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project */ 48f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Projectpublic class SealedObject implements Serializable { 49f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project 50f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project private static final long serialVersionUID = 4482838265551344752L; 51f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project 52f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project /** 53f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project * The {@link AlgorithmParameters} in encoded format. 54f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project */ 55f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project protected byte[] encodedParams; 56f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project private byte[] encryptedContent; 57f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project private String sealAlg; 58f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project private String paramsAlg; 59f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project 60f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project private void readObject(ObjectInputStream s) 61f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project throws IOException, ClassNotFoundException { 62f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project encodedParams = (byte []) s.readUnshared(); 63f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project encryptedContent = (byte []) s.readUnshared(); 64f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project sealAlg = (String) s.readUnshared(); 65f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project paramsAlg = (String) s.readUnshared(); 66f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project } 67f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project 68f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project /** 69f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project * Creates a new {@code SealedObject} instance wrapping the specified object 70f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project * and sealing it using the specified cipher. 71f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project * <p> 72f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project * The cipher must be fully initialized. 738207f1e8dbc63916f238f81dc46567c55090e95bJesse Wilson * 74f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project * @param object 75f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project * the object to seal, can be {@code null}. 76f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project * @param c 77f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project * the cipher to encrypt the object. 78f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project * @throws IOException 79f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project * if the serialization fails. 80f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project * @throws IllegalBlockSizeException 81f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project * if the specified cipher is a block cipher and the length of 82f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project * the serialized data is not a multiple of the ciphers block 83f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project * size. 84f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project * @throws NullPointerException 85f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project * if the cipher is {@code null}. 86f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project */ 87f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project public SealedObject(Serializable object, Cipher c) 88f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project throws IOException, IllegalBlockSizeException { 89f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project if (c == null) { 90f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project throw new NullPointerException(Messages.getString("crypto.13")); //$NON-NLS-1$ 91f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project } 92f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project try { 93f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project ByteArrayOutputStream bos = new ByteArrayOutputStream(); 94f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project ObjectOutputStream oos = new ObjectOutputStream(bos); 95f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project oos.writeObject(object); 96f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project oos.flush(); 97f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project AlgorithmParameters ap = c.getParameters(); 98f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project this.encodedParams = (ap == null) ? null : ap.getEncoded(); 99f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project this.paramsAlg = (ap == null) ? null : ap.getAlgorithm(); 100f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project this.sealAlg = c.getAlgorithm(); 101f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project this.encryptedContent = c.doFinal(bos.toByteArray()); 102f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project } catch (BadPaddingException e) { 103f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project // should be never thrown because the cipher 104f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project // should be initialized for encryption 105f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project throw new IOException(e.toString()); 106f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project } 107f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project } 108f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project 109f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project /** 110f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project * Creates a new {@code SealedObject} instance by copying the data from 111f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project * the specified object. 1128207f1e8dbc63916f238f81dc46567c55090e95bJesse Wilson * 113f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project * @param so 114f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project * the object to copy. 115f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project */ 116f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project protected SealedObject(SealedObject so) { 117f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project if (so == null) { 118f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project throw new NullPointerException(Messages.getString("crypto.14")); //$NON-NLS-1$ 119f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project } 120f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project this.encryptedContent = so.encryptedContent; 121f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project this.encodedParams = so.encodedParams; 122f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project this.sealAlg = so.sealAlg; 123f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project this.paramsAlg = so.paramsAlg; 124f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project } 125f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project 126f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project /** 127f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project * Returns the algorithm this object was sealed with. 1288207f1e8dbc63916f238f81dc46567c55090e95bJesse Wilson * 129f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project * @return the algorithm this object was sealed with. 130f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project */ 131f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project public final String getAlgorithm() { 132f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project return sealAlg; 133f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project } 134f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project 135f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project /** 136f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project * Returns the wrapped object, decrypting it using the specified key. 1378207f1e8dbc63916f238f81dc46567c55090e95bJesse Wilson * 138f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project * @param key 139f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project * the key to decrypt the data with. 140f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project * @return the encapsulated object. 141f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project * @throws IOException 142f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project * if deserialization fails. 143f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project * @throws ClassNotFoundException 144f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project * if deserialization fails. 145f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project * @throws NoSuchAlgorithmException 146f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project * if the algorithm to decrypt the data is not available. 147f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project * @throws InvalidKeyException 148f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project * if the specified key cannot be used to decrypt the data. 149f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project */ 150f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project public final Object getObject(Key key) 151f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project throws IOException, ClassNotFoundException, 152f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project NoSuchAlgorithmException, InvalidKeyException { 153f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project // BEGIN android-added 154f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project if (key == null) { 155f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project throw new InvalidKeyException( 156f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project Messages.getString("crypto.05")); 157f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project } 158f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project // END android-added 159f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project try { 160f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project Cipher cipher = Cipher.getInstance(sealAlg); 161f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project if ((paramsAlg != null) && (paramsAlg.length() != 0)) { 162f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project AlgorithmParameters params = 163f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project AlgorithmParameters.getInstance(paramsAlg); 164f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project params.init(encodedParams); 165f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project cipher.init(Cipher.DECRYPT_MODE, key, params); 166f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project } else { 167f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project cipher.init(Cipher.DECRYPT_MODE, key); 168f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project } 169f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project byte[] serialized = cipher.doFinal(encryptedContent); 170f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project ObjectInputStream ois = 171f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project new ObjectInputStream( 172f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project new ByteArrayInputStream(serialized)); 173f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project return ois.readObject(); 174f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project } catch (NoSuchPaddingException e) { 175f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project // should not be thrown because cipher text was made 176f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project // with existing padding 177f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project throw new NoSuchAlgorithmException(e.toString()); 178f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project } catch (InvalidAlgorithmParameterException e) { 179f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project // should not be thrown because cipher text was made 180f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project // with correct algorithm parameters 181f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project throw new NoSuchAlgorithmException(e.toString()); 182f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project } catch (IllegalBlockSizeException e) { 183f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project // should not be thrown because the cipher text 184f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project // was correctly made 185f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project throw new NoSuchAlgorithmException(e.toString()); 186f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project } catch (BadPaddingException e) { 187f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project // should not be thrown because the cipher text 188f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project // was correctly made 189f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project throw new NoSuchAlgorithmException(e.toString()); 190f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project } catch (IllegalStateException e) { 191f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project // should never be thrown because cipher is initialized 192f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project throw new NoSuchAlgorithmException(e.toString()); 193f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project } 194f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project } 195f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project 196f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project /** 197f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project * Returns the wrapped object, decrypting it using the specified 198f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project * cipher. 1998207f1e8dbc63916f238f81dc46567c55090e95bJesse Wilson * 200f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project * @param c 201f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project * the cipher to decrypt the data. 202f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project * @return the encapsulated object. 203f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project * @throws IOException 204f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project * if deserialization fails. 205f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project * @throws ClassNotFoundException 206f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project * if deserialization fails. 207f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project * @throws IllegalBlockSizeException 208f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project * if the specified cipher is a block cipher and the length of 209f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project * the serialized data is not a multiple of the ciphers block 210f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project * size. 211f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project * @throws BadPaddingException 212f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project * if the padding of the data does not match the padding scheme. 213f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project */ 214f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project public final Object getObject(Cipher c) 215f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project throws IOException, ClassNotFoundException, 216f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project IllegalBlockSizeException, BadPaddingException { 217f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project if (c == null) { 218f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project throw new NullPointerException(Messages.getString("crypto.13")); //$NON-NLS-1$ 219f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project } 220f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project byte[] serialized = c.doFinal(encryptedContent); 221f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project ObjectInputStream ois = 222f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project new ObjectInputStream( 223f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project new ByteArrayInputStream(serialized)); 224f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project return ois.readObject(); 225f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project } 226f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project 227f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project /** 228f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project * Returns the wrapped object, decrypting it using the specified key. The 229f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project * specified provider is used to retrieve the cipher algorithm. 2308207f1e8dbc63916f238f81dc46567c55090e95bJesse Wilson * 231f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project * @param key 232f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project * the key to decrypt the data. 233f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project * @param provider 234f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project * the name of the provider that provides the cipher algorithm. 235f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project * @return the encapsulated object. 236f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project * @throws IOException 237f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project * if deserialization fails. 238f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project * @throws ClassNotFoundException 239f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project * if deserialization fails. 240f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project * @throws NoSuchAlgorithmException 241f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project * if the algorithm used to decrypt the data is not available. 242f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project * @throws NoSuchProviderException 243f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project * if the specified provider is not available. 244f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project * @throws InvalidKeyException 245f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project * if the specified key cannot be used to decrypt the data. 246f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project */ 247f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project public final Object getObject(Key key, String provider) 248f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project throws IOException, ClassNotFoundException, 249f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project NoSuchAlgorithmException, NoSuchProviderException, 250f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project InvalidKeyException { 251f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project if ((provider == null) || (provider.length() == 0)) { 252f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project throw new IllegalArgumentException( 253f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project Messages.getString("crypto.15")); //$NON-NLS-1$ 254f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project } 255f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project try { 256f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project Cipher cipher = Cipher.getInstance(sealAlg, provider); 257f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project if ((paramsAlg != null) && (paramsAlg.length() != 0)) { 258f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project AlgorithmParameters params = 259f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project AlgorithmParameters.getInstance(paramsAlg); 260f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project params.init(encodedParams); 261f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project cipher.init(Cipher.DECRYPT_MODE, key, params); 262f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project } else { 263f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project cipher.init(Cipher.DECRYPT_MODE, key); 264f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project } 265f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project byte[] serialized = cipher.doFinal(encryptedContent); 266f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project ObjectInputStream ois = 267f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project new ObjectInputStream( 268f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project new ByteArrayInputStream(serialized)); 269f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project return ois.readObject(); 270f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project } catch (NoSuchPaddingException e) { 271f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project // should not be thrown because cipher text was made 272f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project // with existing padding 273f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project throw new NoSuchAlgorithmException(e.toString()); 274f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project } catch (InvalidAlgorithmParameterException e) { 275f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project // should not be thrown because cipher text was made 276f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project // with correct algorithm parameters 277f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project throw new NoSuchAlgorithmException(e.toString()); 278f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project } catch (IllegalBlockSizeException e) { 279f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project // should not be thrown because the cipher text 280f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project // was correctly made 281f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project throw new NoSuchAlgorithmException(e.toString()); 282f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project } catch (BadPaddingException e) { 283f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project // should not be thrown because the cipher text 284f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project // was correctly made 285f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project throw new NoSuchAlgorithmException(e.toString()); 286f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project } catch (IllegalStateException e) { 287f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project // should never be thrown because cipher is initialized 288f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project throw new NoSuchAlgorithmException(e.toString()); 289f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project } 290f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project } 291f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project} 292f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project 293