SealedObject.java revision 2ad60cfc28e14ee8f0bb038720836a4696c478ad
1/* 2 * Licensed to the Apache Software Foundation (ASF) under one or more 3 * contributor license agreements. See the NOTICE file distributed with 4 * this work for additional information regarding copyright ownership. 5 * The ASF licenses this file to You under the Apache License, Version 2.0 6 * (the "License"); you may not use this file except in compliance with 7 * the License. You may obtain a copy of the License at 8 * 9 * http://www.apache.org/licenses/LICENSE-2.0 10 * 11 * Unless required by applicable law or agreed to in writing, software 12 * distributed under the License is distributed on an "AS IS" BASIS, 13 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 14 * See the License for the specific language governing permissions and 15 * limitations under the License. 16 */ 17 18/** 19* @author Alexander Y. Kleymenov 20* @version $Revision$ 21*/ 22 23package javax.crypto; 24 25import java.io.ByteArrayInputStream; 26import java.io.ByteArrayOutputStream; 27import java.io.IOException; 28import java.io.ObjectInputStream; 29import java.io.ObjectOutputStream; 30import java.io.Serializable; 31import java.security.AlgorithmParameters; 32import java.security.InvalidAlgorithmParameterException; 33import java.security.InvalidKeyException; 34import java.security.Key; 35import java.security.NoSuchAlgorithmException; 36import java.security.NoSuchProviderException; 37import javax.crypto.IllegalBlockSizeException; 38import javax.crypto.NoSuchPaddingException; 39 40import org.apache.harmony.crypto.internal.nls.Messages; 41 42/** 43 * @com.intel.drl.spec_ref 44 */ 45public class SealedObject implements Serializable { 46 47 // the value of this field was derived by using serialver utility 48 /** 49 * @com.intel.drl.spec_ref 50 */ 51 private static final long serialVersionUID = 4482838265551344752L; 52 53 /** 54 * @com.intel.drl.spec_ref 55 */ 56 protected byte[] encodedParams; 57 private byte[] encryptedContent; 58 private String sealAlg; 59 private String paramsAlg; 60 61 private void readObject(ObjectInputStream s) 62 throws IOException, ClassNotFoundException { 63 encodedParams = (byte []) s.readUnshared(); 64 encryptedContent = (byte []) s.readUnshared(); 65 sealAlg = (String) s.readUnshared(); 66 paramsAlg = (String) s.readUnshared(); 67 } 68 69 /** 70 * @com.intel.drl.spec_ref 71 */ 72 public SealedObject(Serializable object, Cipher c) 73 throws IOException, IllegalBlockSizeException { 74 if (c == null) { 75 throw new NullPointerException(Messages.getString("crypto.13")); //$NON-NLS-1$ 76 } 77 try { 78 ByteArrayOutputStream bos = new ByteArrayOutputStream(); 79 ObjectOutputStream oos = new ObjectOutputStream(bos); 80 oos.writeObject(object); 81 oos.flush(); 82 AlgorithmParameters ap = c.getParameters(); 83 this.encodedParams = (ap == null) ? null : ap.getEncoded(); 84 this.paramsAlg = (ap == null) ? null : ap.getAlgorithm(); 85 this.sealAlg = c.getAlgorithm(); 86 this.encryptedContent = c.doFinal(bos.toByteArray()); 87 } catch (BadPaddingException e) { 88 // should be never thrown because the cipher 89 // should be initialized for encryption 90 throw new IOException(e.toString()); 91 } 92 } 93 94 /** 95 * @com.intel.drl.spec_ref 96 */ 97 protected SealedObject(SealedObject so) { 98 if (so == null) { 99 throw new NullPointerException(Messages.getString("crypto.14")); //$NON-NLS-1$ 100 } 101 this.encryptedContent = so.encryptedContent; 102 this.encodedParams = so.encodedParams; 103 this.sealAlg = so.sealAlg; 104 this.paramsAlg = so.paramsAlg; 105 } 106 107 /** 108 * @com.intel.drl.spec_ref 109 */ 110 public final String getAlgorithm() { 111 return sealAlg; 112 } 113 114 /** 115 * @com.intel.drl.spec_ref 116 */ 117 public final Object getObject(Key key) 118 throws IOException, ClassNotFoundException, 119 NoSuchAlgorithmException, InvalidKeyException { 120 try { 121 Cipher cipher = Cipher.getInstance(sealAlg); 122 if ((paramsAlg != null) && (paramsAlg.length() != 0)) { 123 AlgorithmParameters params = 124 AlgorithmParameters.getInstance(paramsAlg); 125 params.init(encodedParams); 126 cipher.init(Cipher.DECRYPT_MODE, key, params); 127 } else { 128 cipher.init(Cipher.DECRYPT_MODE, key); 129 } 130 byte[] serialized = cipher.doFinal(encryptedContent); 131 ObjectInputStream ois = 132 new ObjectInputStream( 133 new ByteArrayInputStream(serialized)); 134 return ois.readObject(); 135 } catch (NoSuchPaddingException e) { 136 // should not be thrown because cipher text was made 137 // with existing padding 138 throw new NoSuchAlgorithmException(e.toString()); 139 } catch (InvalidAlgorithmParameterException e) { 140 // should not be thrown because cipher text was made 141 // with correct algorithm parameters 142 throw new NoSuchAlgorithmException(e.toString()); 143 } catch (IllegalBlockSizeException e) { 144 // should not be thrown because the cipher text 145 // was correctly made 146 throw new NoSuchAlgorithmException(e.toString()); 147 } catch (BadPaddingException e) { 148 // should not be thrown because the cipher text 149 // was correctly made 150 throw new NoSuchAlgorithmException(e.toString()); 151 } catch (IllegalStateException e) { 152 // should never be thrown because cipher is initialized 153 throw new NoSuchAlgorithmException(e.toString()); 154 } 155 } 156 157 /** 158 * @com.intel.drl.spec_ref 159 */ 160 public final Object getObject(Cipher c) 161 throws IOException, ClassNotFoundException, 162 IllegalBlockSizeException, BadPaddingException { 163 if (c == null) { 164 throw new NullPointerException(Messages.getString("crypto.13")); //$NON-NLS-1$ 165 } 166 byte[] serialized = c.doFinal(encryptedContent); 167 ObjectInputStream ois = 168 new ObjectInputStream( 169 new ByteArrayInputStream(serialized)); 170 return ois.readObject(); 171 } 172 173 /** 174 * @com.intel.drl.spec_ref 175 */ 176 public final Object getObject(Key key, String provider) 177 throws IOException, ClassNotFoundException, 178 NoSuchAlgorithmException, NoSuchProviderException, 179 InvalidKeyException { 180 if ((provider == null) || (provider.length() == 0)) { 181 throw new IllegalArgumentException( 182 Messages.getString("crypto.15")); //$NON-NLS-1$ 183 } 184 try { 185 Cipher cipher = Cipher.getInstance(sealAlg, provider); 186 if ((paramsAlg != null) && (paramsAlg.length() != 0)) { 187 AlgorithmParameters params = 188 AlgorithmParameters.getInstance(paramsAlg); 189 params.init(encodedParams); 190 cipher.init(Cipher.DECRYPT_MODE, key, params); 191 } else { 192 cipher.init(Cipher.DECRYPT_MODE, key); 193 } 194 byte[] serialized = cipher.doFinal(encryptedContent); 195 ObjectInputStream ois = 196 new ObjectInputStream( 197 new ByteArrayInputStream(serialized)); 198 return ois.readObject(); 199 } catch (NoSuchPaddingException e) { 200 // should not be thrown because cipher text was made 201 // with existing padding 202 throw new NoSuchAlgorithmException(e.toString()); 203 } catch (InvalidAlgorithmParameterException e) { 204 // should not be thrown because cipher text was made 205 // with correct algorithm parameters 206 throw new NoSuchAlgorithmException(e.toString()); 207 } catch (IllegalBlockSizeException e) { 208 // should not be thrown because the cipher text 209 // was correctly made 210 throw new NoSuchAlgorithmException(e.toString()); 211 } catch (BadPaddingException e) { 212 // should not be thrown because the cipher text 213 // was correctly made 214 throw new NoSuchAlgorithmException(e.toString()); 215 } catch (IllegalStateException e) { 216 // should never be thrown because cipher is initialized 217 throw new NoSuchAlgorithmException(e.toString()); 218 } 219 } 220} 221 222