blob: 5084db5c4328e25a4cb33cc980076107870fe655 [file] [log] [blame]
J. Duke319a3b92007-12-01 00:00:00 +00001/*
2 * Copyright 2004-2007 Sun Microsystems, Inc. All Rights Reserved.
3 * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
4 *
5 * This code is free software; you can redistribute it and/or modify it
6 * under the terms of the GNU General Public License version 2 only, as
7 * published by the Free Software Foundation.
8 *
9 * This code is distributed in the hope that it will be useful, but WITHOUT
10 * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
11 * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
12 * version 2 for more details (a copy is included in the LICENSE file that
13 * accompanied this code).
14 *
15 * You should have received a copy of the GNU General Public License version
16 * 2 along with this work; if not, write to the Free Software Foundation,
17 * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
18 *
19 * Please contact Sun Microsystems, Inc., 4150 Network Circle, Santa Clara,
20 * CA 95054 USA or visit www.sun.com if you need additional information or
21 * have any questions.
22 */
23
24/*
25 * @test
26 * @bug 4979126
27 * @summary Ensure update()/doFinal() matches javadoc description
28 * when ShortBufferException is thrown.
29 * @author Valerie Peng
30 */
31import java.util.Arrays;
32import java.security.*;
33import java.security.spec.*;
34import java.math.BigInteger;
35import javax.crypto.*;
36import javax.crypto.spec.*;
37import java.security.Provider;
38import com.sun.crypto.provider.*;
39
40public class TestShortBuffer {
41 private static final String ALGO = "AES";
42 private static final String[] MODES = {
43 "ECB", "CBC", "PCBC", "CFB16", "OFB8"
44 };
45 private static final SecretKey KEY =
46 new SecretKeySpec(new byte[16], ALGO);
47 private static byte[] SHORTBUFFER = new byte[1];
48
49 private static final byte[] PLAINTEXT = new byte[30];
50 static {
51 PLAINTEXT[0] = (byte)0x15;
52 };
53 private Cipher ci = null;
54 private byte[] in = null;
55 private byte[] expected = null;
56 private byte[] out = null;
57 private int outOffset = 0;
58
59 private TestShortBuffer(Cipher ci) {
60 this.ci = ci;
61 }
62
63 private void init(byte[] in, byte[] expected) {
64 this.in = (byte[]) in.clone();
65 this.expected = (byte[]) expected.clone();
66 this.out = new byte[expected.length];
67 this.outOffset = 0;
68 }
69
70 private static void runTest() throws Exception {
71 // Initialization
72 for (int i = 0; i < MODES.length; i++) {
73 System.out.println("===== TESTING MODE " + MODES[i] + " =====");
74 Cipher ci = Cipher.getInstance(ALGO+"/"+MODES[i]+"/PKCS5Padding",
75 "SunJCE");
76 TestShortBuffer test = null;
77 int stored = 0;
78 AlgorithmParameters params = null;
79 byte[] cipherText = null;
80 byte[] shortBuffer = new byte[8];
81 for (int k = 0; k < 2; k++) {
82 byte[] expected = null;
83 switch (k) {
84 case 0: // Encryption
85 System.out.println("Testing with Cipher.ENCRYPT_MODE");
86 ci.init(Cipher.ENCRYPT_MODE, KEY);
87 cipherText = ci.doFinal(PLAINTEXT);
88 test = new TestShortBuffer(ci);
89 test.init(PLAINTEXT, cipherText);
90 params = ci.getParameters();
91 break;
92 case 1: // Decryption
93 System.out.println("Testing with Cipher.DECRYPT_MODE");
94 ci.init(Cipher.DECRYPT_MODE, KEY, params);
95 test = new TestShortBuffer(ci);
96 test.init(cipherText, PLAINTEXT);
97 break;
98 }
99 int offset = 2 + i*5;
100 test.testUpdate();
101 test.testUpdateWithUpdate(offset);
102 test.testDoFinal();
103 test.testDoFinalWithUpdate(offset);
104 }
105 }
106 }
107
108 private void checkOutput() throws Exception {
109 if (!Arrays.equals(out, expected)) {
110 System.out.println("got: " + new BigInteger(out));
111 System.out.println("expect: " + new BigInteger(expected));
112 throw new Exception("Generated different outputs");
113 }
114 }
115 private void testUpdate() throws Exception {
116 outOffset = 0;
117 int stored = 0;
118 try {
119 stored = ci.update(in, 0, in.length, SHORTBUFFER);
120 throw new Exception("Should throw ShortBufferException!");
121 } catch (ShortBufferException sbe) {
122 System.out.println("Expected SBE thrown....");
123 // retry with a large-enough buffer according to javadoc
124 stored = ci.update(in, 0, in.length, out);
125 stored = ci.doFinal(out, outOffset += stored);
126 if (out.length != (stored + outOffset)) {
127 throw new Exception("Wrong number of output bytes");
128 }
129 }
130 checkOutput();
131 }
132 private void testUpdateWithUpdate(int offset) throws Exception {
133 outOffset = 0;
134 int stored = 0;
135 byte[] out1 = ci.update(in, 0, offset);
136 if (out1 != null) {
137 System.arraycopy(out1, 0, out, 0, out1.length);
138 outOffset += out1.length;
139 }
140 try {
141 stored = ci.update(in, offset, in.length-offset, SHORTBUFFER);
142 throw new Exception("Should throw ShortBufferException!");
143 } catch (ShortBufferException sbe) {
144 System.out.println("Expected SBE thrown....");
145 // retry with a large-enough buffer according to javadoc
146 stored = ci.update(in, offset, in.length-offset,
147 out, outOffset);
148 stored = ci.doFinal(out, outOffset+=stored);
149 if (out.length != (stored + outOffset)) {
150 throw new Exception("Wrong number of output bytes");
151 }
152 }
153 checkOutput();
154 }
155 private void testDoFinal() throws Exception {
156 outOffset = 0;
157 int stored = 0;
158 try {
159 stored = ci.doFinal(in, 0, in.length, SHORTBUFFER);
160 throw new Exception("Should throw ShortBufferException!");
161 } catch (ShortBufferException sbe) {
162 System.out.println("Expected SBE thrown....");
163 // retry with a large-enough buffer according to javadoc
164 stored = ci.doFinal(in, 0, in.length, out, 0);
165 if (out.length != stored) {
166 throw new Exception("Wrong number of output bytes");
167 }
168 }
169 checkOutput();
170 }
171
172 private void testDoFinalWithUpdate(int offset) throws Exception {
173 outOffset = 0;
174 int stored = 0;
175 byte[] out1 = ci.update(in, 0, offset);
176 if (out1 != null) {
177 System.arraycopy(out1, 0, out, 0, out1.length);
178 outOffset += out1.length;
179 }
180 try {
181 stored = ci.doFinal(in, offset, in.length-offset, SHORTBUFFER);
182 throw new Exception("Should throw ShortBufferException!");
183 } catch (ShortBufferException sbe) {
184 System.out.println("Expected SBE thrown....");
185 // retry with a large-enough buffer according to javadoc
186 stored = ci.doFinal(in, offset, in.length-offset,
187 out, outOffset);
188 if (out.length != (stored + outOffset)) {
189 throw new Exception("Wrong number of output bytes");
190 }
191 }
192 checkOutput();
193 }
194 public static void main(String[] argv) throws Exception {
195 runTest();
196 System.out.println("Test Passed");
197 }
198}