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
22package javax.crypto;
23
24import java.io.ByteArrayInputStream;
25import java.io.ByteArrayOutputStream;
26import java.io.ObjectInputStream;
27import java.io.ObjectOutputStream;
28import java.security.Key;
29import java.security.InvalidKeyException;
30import java.util.Arrays;
31import javax.crypto.Cipher;
32import javax.crypto.KeyGenerator;
33import javax.crypto.NullCipher;
34import javax.crypto.spec.IvParameterSpec;
35import javax.crypto.spec.SecretKeySpec;
36
37import junit.framework.TestCase;
38
39/**
40 */
41
42public 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     */
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     */
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     */
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     */
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     */
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     */
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     */
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
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