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 Vera Y. Petrashkova
20*/
21
22package javax.crypto;
23
24import java.security.spec.AlgorithmParameterSpec;
25import java.security.InvalidAlgorithmParameterException;
26import java.security.InvalidKeyException;
27import java.security.Key;
28import java.security.NoSuchAlgorithmException;
29import java.security.SecureRandom;
30import java.security.AlgorithmParameters;
31import java.nio.ByteBuffer;
32
33import junit.framework.TestCase;
34
35
36/**
37 * Tests for <code>CipherSpi</code> class constructors and methods.
38 *
39 */
40
41public class CipherSpiTest extends TestCase {
42
43    /**
44     * Constructor for CipherSpiTests.
45     *
46     * @param arg0
47     */
48    public CipherSpiTest(String arg0) {
49        super(arg0);
50    }
51
52    /**
53     * Test for <code>CipherSpi</code> constructor
54     * Assertion: constructs CipherSpi
55     */
56    public void testCipherSpiTests01() throws IllegalBlockSizeException,
57            BadPaddingException, ShortBufferException {
58
59        CipherSpi cSpi = new myCipherSpi();
60        assertEquals("BlockSize is not 0", cSpi.engineGetBlockSize(), 0);
61        assertEquals("OutputSize is not 0", cSpi.engineGetOutputSize(1), 0);
62        byte[] bb = cSpi.engineGetIV();
63        assertEquals("Length of result byte array is not 0", bb.length, 0);
64        assertNull("Not null result", cSpi.engineGetParameters());
65        byte[] bb1 = new byte[10];
66        byte[] bb2 = new byte[10];
67        bb = cSpi.engineUpdate(bb1, 1, 2);
68        assertEquals("Incorrect result of engineUpdate(byte, int, int)",
69                bb.length, 2);
70        bb = cSpi.engineDoFinal(bb1, 1, 2);
71        assertEquals("Incorrect result of engineDoFinal(byte, int, int)", 2,
72                bb.length);
73        assertEquals(
74                "Incorrect result of engineUpdate(byte, int, int, byte, int)",
75                cSpi.engineUpdate(bb1, 1, 2, bb2, 7), 2);
76        assertEquals(
77                "Incorrect result of engineDoFinal(byte, int, int, byte, int)",
78                2, cSpi.engineDoFinal(bb1, 1, 2, bb2, 0));
79    }
80
81    /**
82     * Test for <code>engineGetKeySize(Key)</code> method
83     * Assertion: It throws UnsupportedOperationException if it is not overridden
84     */
85    public void testCipherSpi02() throws Exception {
86        CipherSpi cSpi = new myCipherSpi();
87        try {
88            cSpi.engineGetKeySize(null);
89            fail("UnsupportedOperationException must be thrown");
90        } catch (UnsupportedOperationException e) {
91        }
92    }
93
94    /**
95     * Test for <code>engineWrap(Key)</code> method
96     * Assertion: It throws UnsupportedOperationException if it is not overridden
97     */
98    public void testCipherSpi03() throws Exception {
99        CipherSpi cSpi = new myCipherSpi();
100        try {
101            cSpi.engineWrap(null);
102            fail("UnsupportedOperationException must be thrown");
103        } catch (UnsupportedOperationException e) {
104        }
105    }
106
107    /**
108     * Test for <code>engineUnwrap(byte[], String, int)</code> method
109     * Assertion: It throws UnsupportedOperationException if it is not overridden
110     */
111    public void testCipherSpi04() throws Exception {
112        CipherSpi cSpi = new myCipherSpi();
113        try {
114            cSpi.engineUnwrap(new byte[0], "", 0);
115            fail("UnsupportedOperationException must be thrown");
116        } catch (UnsupportedOperationException e) {
117        }
118    }
119
120    /**
121     * Test for <code>engineUpdate(ByteBuffer, ByteBuffer)</code> method
122     * Assertions:
123     * throws NullPointerException if one of these buffers is null;
124     * throws ShortBufferException is there is no space in output to hold result
125     */
126    public void testCipherSpi05() throws ShortBufferException {
127        CipherSpi cSpi = new myCipherSpi();
128        byte[] bb = { (byte) 0, (byte) 1, (byte) 2, (byte) 3, (byte) 4,
129                (byte) 5, (byte) 6, (byte) 7, (byte) 8, (byte) 9, (byte) 10 };
130        int pos = 5;
131        int len = bb.length;
132        ByteBuffer bbNull = null;
133        ByteBuffer bb1 = ByteBuffer.allocate(len);
134        bb1.put(bb);
135        bb1.position(0);
136        try {
137            cSpi.engineUpdate(bbNull, bb1);
138            fail("NullPointerException must be thrown");
139        } catch (NullPointerException e) {
140        }
141        try {
142            cSpi.engineUpdate(bb1, bbNull);
143            fail("NullPointerException must be thrown");
144        } catch (NullPointerException e) {
145        }
146        ByteBuffer bb2 = ByteBuffer.allocate(bb.length);
147        bb1.position(len);
148        assertEquals("Incorrect number of stored bytes", 0, cSpi.engineUpdate(
149                bb1, bb2));
150
151        bb1.position(0);
152        bb2.position(len - 2);
153        try {
154            cSpi.engineUpdate(bb1, bb2);
155            fail("ShortBufferException bust be thrown. Output buffer remaining: "
156                    .concat(Integer.toString(bb2.remaining())));
157        } catch (ShortBufferException e) {
158        }
159        bb1.position(10);
160        bb2.position(0);
161        assertTrue("Incorrect number of stored bytes", cSpi.engineUpdate(bb1,
162                bb2) > 0);
163        bb1.position(bb.length);
164        cSpi.engineUpdate(bb1, bb2);
165
166        bb1.position(pos);
167        bb2.position(0);
168        int res = cSpi.engineUpdate(bb1, bb2);
169        assertTrue("Incorrect result", res > 0);
170    }
171
172    /**
173     * Test for <code>engineDoFinal(ByteBuffer, ByteBuffer)</code> method
174     * Assertions:
175     * throws NullPointerException if one of these buffers is null;
176     * throws ShortBufferException is there is no space in output to hold result
177     */
178    public void testCipherSpi06() throws BadPaddingException,
179            ShortBufferException, IllegalBlockSizeException {
180        CipherSpi cSpi = new myCipherSpi();
181        int len = 10;
182        byte[] bbuf = new byte[len];
183        for (int i = 0; i < bbuf.length; i++) {
184            bbuf[i] = (byte) i;
185        }
186        ByteBuffer bb1 = ByteBuffer.wrap(bbuf);
187        ByteBuffer bbNull = null;
188        try {
189            cSpi.engineDoFinal(bbNull, bb1);
190            fail("NullPointerException must be thrown");
191        } catch (NullPointerException e) {
192        }
193        try {
194            cSpi.engineDoFinal(bb1, bbNull);
195            fail("NullPointerException must be thrown");
196        } catch (NullPointerException e) {
197        }
198        ByteBuffer bb2 = ByteBuffer.allocate(len);
199        bb1.position(bb1.limit());
200        assertEquals("Incorrect result", 0, cSpi.engineDoFinal(bb1, bb2));
201
202        bb1.position(0);
203        bb2.position(len - 2);
204        try {
205            cSpi.engineDoFinal(bb1, bb2);
206            fail("ShortBufferException must be thrown. Output buffer remaining: "
207                    .concat(Integer.toString(bb2.remaining())));
208        } catch (ShortBufferException e) {
209        }
210        int pos = 5;
211        bb1.position(pos);
212        bb2.position(0);
213        assertTrue("Incorrect result", cSpi.engineDoFinal(bb1, bb2) > 0);
214    }
215}
216/**
217 *
218 * Additional class for CipherGeneratorSpi constructor verification
219 */
220
221class myCipherSpi extends CipherSpi {
222    private byte[] initV;
223
224    private static byte[] resV = { (byte) 7, (byte) 6, (byte) 5, (byte) 4,
225            (byte) 3, (byte) 2, (byte) 1, (byte) 0 };
226
227    public myCipherSpi() {
228        this.initV = new byte[0];
229    }
230
231    protected void engineSetMode(String mode) throws NoSuchAlgorithmException {
232    }
233
234    protected void engineSetPadding(String padding)
235            throws NoSuchPaddingException {
236    }
237
238    protected int engineGetBlockSize() {
239        return 0;
240    }
241
242    protected int engineGetOutputSize(int inputLen) {
243        return 0;
244    }
245
246    protected byte[] engineGetIV() {
247        return new byte[0];
248    }
249
250    protected AlgorithmParameters engineGetParameters() {
251        return null;
252    }
253
254    protected void engineInit(int opmode, Key key, SecureRandom random)
255            throws InvalidKeyException {
256    }
257
258    protected void engineInit(int opmode, Key key,
259            AlgorithmParameterSpec params, SecureRandom random)
260            throws InvalidKeyException, InvalidAlgorithmParameterException {
261    }
262
263    protected void engineInit(int opmode, Key key, AlgorithmParameters params,
264            SecureRandom random) throws InvalidKeyException,
265            InvalidAlgorithmParameterException {
266    }
267
268    protected byte[] engineUpdate(byte[] input, int inputOffset, int inputLen) {
269        if (initV.length < inputLen) {
270            initV = new byte[inputLen];
271        }
272        for (int i = 0; i < inputLen; i++) {
273            initV[i] = input[inputOffset + i];
274        }
275        return initV;
276    }
277
278    protected int engineUpdate(byte[] input, int inputOffset, int inputLen,
279            byte[] output, int outputOffset) throws ShortBufferException {
280        byte []res = engineUpdate(input, inputOffset, inputLen);
281        int t = res.length;
282        if ((output.length - outputOffset) < t) {
283            throw new ShortBufferException("Update");
284        }
285        for (int i = 0; i < t; i++) {
286            output[i + outputOffset] = initV[i];
287        }
288        return t;
289    }
290
291    protected byte[] engineDoFinal(byte[] input, int inputOffset, int inputLen)
292            throws IllegalBlockSizeException, BadPaddingException {
293        if (resV.length > inputLen) {
294            byte[] bb = new byte[inputLen];
295            for (int i = 0; i < inputLen; i++) {
296                bb[i] = resV[i];
297            }
298            return bb;
299        }
300        return resV;
301    }
302
303    protected int engineDoFinal(byte[] input, int inputOffset, int inputLen,
304            byte[] output, int outputOffset) throws ShortBufferException,
305            IllegalBlockSizeException, BadPaddingException {
306        byte[] res = engineDoFinal(input, inputOffset, inputLen);
307
308        int t = res.length;
309        if ((output.length - outputOffset) < t) {
310            throw new ShortBufferException("DoFinal");
311        }
312        for (int i = 0; i < t; i++) {
313            output[i + outputOffset] = res[i];
314        }
315        return t;
316    }
317
318
319    protected int engineUpdate(ByteBuffer input, ByteBuffer output)
320    throws ShortBufferException {
321        return super.engineUpdate(input, output);
322    }
323    protected int engineDoFinal(ByteBuffer input, ByteBuffer output)
324    throws ShortBufferException, IllegalBlockSizeException,
325    BadPaddingException {
326        return super.engineDoFinal(input, output);
327    }
328}
329