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  */
21 
22 package javax.crypto;
23 
24 import java.io.ByteArrayInputStream;
25 import java.io.ByteArrayOutputStream;
26 import java.io.ObjectInputStream;
27 import java.io.ObjectOutputStream;
28 import java.security.Key;
29 import java.security.InvalidKeyException;
30 import java.util.Arrays;
31 import javax.crypto.Cipher;
32 import javax.crypto.KeyGenerator;
33 import javax.crypto.NullCipher;
34 import javax.crypto.spec.IvParameterSpec;
35 import javax.crypto.spec.SecretKeySpec;
36 
37 import junit.framework.TestCase;
38 
39 /**
40  */
41 
42 public class SealedObjectTest extends TestCase {
43 
44     /**
45      * readObject(ObjectInputStream s) method testing. Tests if the
46      * serialization/deserialization works correctly: object is serialized,
47      * deserialized, the content od deserialized object equals to the
48      * content of initial object.
49      */
testReadObject()50     public void testReadObject() throws Exception {
51         String secret = "secret string";
52         SealedObject so = new SealedObject(secret, new NullCipher());
53         ByteArrayOutputStream bos = new ByteArrayOutputStream();
54         ObjectOutputStream oos = new ObjectOutputStream(bos);
55         oos.writeObject(so);
56 
57         ObjectInputStream ois = new ObjectInputStream(new ByteArrayInputStream(
58                 bos.toByteArray()));
59 
60         SealedObject so_des = (SealedObject) ois.readObject();
61         assertEquals("The secret content of deserialized object "
62                 + "should be equal to the secret content of initial object",
63                 secret, so_des.getObject(new NullCipher()));
64         assertEquals("The value returned by getAlgorithm() method of "
65                 + "deserialized object should be equal to the value returned "
66                 + "by getAlgorithm() method of initial object", so
67                 .getAlgorithm(), so_des.getAlgorithm());
68     }
69 
70     /**
71      * SealedObject(Serializable object, Cipher c) method testing. Tests if the
72      * NullPointerException is thrown in the case of null cipher.
73      */
testSealedObject1()74     public void testSealedObject1() throws Exception {
75         String secret = "secret string";
76         try {
77             new SealedObject(secret, null);
78             fail("NullPointerException should be thrown in the case "
79                     + "of null cipher.");
80         } catch (NullPointerException e) {
81         }
82     }
83 
84     /**
85      * SealedObject(SealedObject so) method testing. Tests if the
86      * NullPointerException is thrown in the case of null SealedObject.
87      */
testSealedObject2()88     public void testSealedObject2() throws Exception {
89         try {
90             new SealedObject(null);
91             fail("NullPointerException should be thrown in the case "
92                     + "of null SealedObject.");
93         } catch (NullPointerException e) {
94         }
95 
96         String secret = "secret string";
97         Cipher cipher = new NullCipher();
98         SealedObject so1 = new SealedObject(secret, cipher);
99         SealedObject so2 = new SealedObject(so1);
100 
101         assertEquals("The secret content of the object should equals "
102                 + "to the secret content of initial object.", secret, so2
103                 .getObject(cipher));
104         assertEquals("The algorithm which was used to seal the object "
105                 + "should be the same as the algorithm used to seal the "
106                 + "initial object", so1.getAlgorithm(), so2.getAlgorithm());
107     }
108 
109     /**
110      * getAlgorithm() method testing. Tests if the returned value equals to the
111      * corresponding value of Cipher object.
112      */
testGetAlgorithm()113     public void testGetAlgorithm() throws Exception {
114         String secret = "secret string";
115         String algorithm = "DES";
116         KeyGenerator kg = KeyGenerator.getInstance(algorithm);
117         Key key = kg.generateKey();
118 
119         Cipher cipher = Cipher.getInstance(algorithm);
120         cipher.init(Cipher.ENCRYPT_MODE, key);
121         SealedObject so = new SealedObject(secret, cipher);
122 
123         assertEquals("The algorithm name should be the same as used "
124                 + "in cipher.", algorithm, so.getAlgorithm());
125     }
126 
127     /**
128      * getObject(Key key) method testing. Tests if the object sealed with
129      * encryption algorithm and specified parameters can be retrieved by
130      * specifying the cryptographic key.
131      */
testGetObject1()132     public void testGetObject1() throws Exception {
133         KeyGenerator kg = KeyGenerator.getInstance("DES");
134         Key key = kg.generateKey();
135 
136         IvParameterSpec ips = new IvParameterSpec(new byte[] { 1, 2, 3, 4, 5,
137                 6, 7, 8 });
138 
139         Cipher cipher = Cipher.getInstance("DES/CBC/PKCS5Padding");
140         cipher.init(Cipher.ENCRYPT_MODE, key, ips);
141 
142         String secret = "secret string";
143         SealedObject so = new SealedObject(secret, cipher);
144 
145         assertEquals("The returned object does not equals to the "
146                 + "original object.", secret, so.getObject(key));
147 
148         assertTrue("The encodedParams field of SealedObject object "
149                 + "should contain the encoded algorithm parameters.", Arrays
150                 .equals(so.encodedParams, cipher.getParameters().getEncoded()));
151     }
152 
153     /**
154      * getObject(Cipher c) method testing. Tests if the proper exception is
155      * thrown in the case of incorrect input parameters and if the object sealed
156      * with encryption algorithm and specified parameters can be retrieved by
157      * specifying the initialized Cipher object.
158      */
testGetObject2()159     public void testGetObject2() throws Exception {
160         try {
161             new SealedObject("secret string", new NullCipher())
162                     .getObject((Cipher) null);
163             fail("NullPointerException should be thrown in the case of "
164                     + "null cipher.");
165         } catch (NullPointerException e) {
166         }
167 
168         KeyGenerator kg = KeyGenerator.getInstance("DES");
169         Key key = kg.generateKey();
170 
171         IvParameterSpec ips = new IvParameterSpec(new byte[] { 1, 2, 3, 4, 5,
172                 6, 7, 8 });
173 
174         Cipher cipher = Cipher.getInstance("DES/CBC/PKCS5Padding");
175         cipher.init(Cipher.ENCRYPT_MODE, key, ips);
176 
177         String secret = "secret string";
178         SealedObject so = new SealedObject(secret, cipher);
179 
180         cipher.init(Cipher.DECRYPT_MODE, key, ips);
181         assertEquals("The returned object does not equals to the "
182                 + "original object.", secret, so.getObject(cipher));
183     }
184 
185     /**
186      * getObject(Key key, String provider) method testing. Tests if the proper
187      * exception is thrown in the case of incorrect input parameters and if the
188      * object sealed with encryption algorithm can be retrieved by specifying
189      * the cryptographic key and provider name.
190      */
testGetObject3()191     public void testGetObject3() throws Exception {
192         try {
193             new SealedObject("secret string", new NullCipher()).getObject(
194                     new SecretKeySpec(new byte[] { 0, 0, 0 }, "algorithm"),
195                     null);
196             fail("IllegalArgumentException should be thrown in the case of "
197                     + "null provider.");
198         } catch (IllegalArgumentException e) {
199         }
200 
201         try {
202             new SealedObject("secret string", new NullCipher()).getObject(
203                     new SecretKeySpec(new byte[] { 0, 0, 0 }, "algorithm"), "");
204             fail("IllegalArgumentException should be thrown in the case of "
205                     + "empty provider.");
206         } catch (IllegalArgumentException e) {
207         }
208 
209         KeyGenerator kg = KeyGenerator.getInstance("DES");
210         Key key = kg.generateKey();
211 
212         Cipher cipher = Cipher.getInstance("DES");
213         String provider = cipher.getProvider().getName();
214         cipher.init(Cipher.ENCRYPT_MODE, key);
215 
216         String secret = "secret string";
217         SealedObject so = new SealedObject(secret, cipher);
218 
219         cipher.init(Cipher.DECRYPT_MODE, key);
220         assertEquals("The returned object does not equals to the "
221                 + "original object.", secret, so.getObject(key, provider));
222     }
223 
224     // Regression test for HARMONY-6347
testGetObject4()225     public void testGetObject4() throws Exception {
226         try {
227             new SealedObject("secret string",
228                     new NullCipher()).getObject((Key) null);
229             fail("NullPointerException should be thrown when key is null");
230         } catch (NullPointerException e) {
231         }
232     }
233 
234 }
235 
236