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