SHA1_MessageDigestTest.java revision e98fbf8686c5289bf03fe5c3de7ff82d3a77104d
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 * TODO 20 * Two testcases, one in testDigestbyteArrayintint01() and one in testUpdatebyteArrayintint01(), 21 * and testUpdatebyteArrayintint03() test are commented out because 22 * current implementations of the MessageDigest and MessageDigestSpi classes 23 * are not compatible with RI; see JIRA ## 1120 and 1148. 24 */ 25 26 27package org.apache.harmony.security.tests.provider.crypto; 28 29 30import java.security.MessageDigest; 31import java.security.DigestException; 32 33import junit.framework.Test; 34import junit.framework.TestCase; 35import junit.framework.TestSuite; 36 37 38/** 39 * Tests against methods in MessageDigest class object using SHA1_MessageDigestImpl. 40 */ 41 42 43public class SHA1_MessageDigestTest extends TestCase { 44 45 46 /* 47 * Data to compare with reference implementation; 48 * they were received by getting hash values for 11 messages 49 * whose length are in the LENGTHS array below. 50 * Numbers in the LENGTH array cover diapason from 1 to 9999 51 */ 52 private static final byte[][] HASHTOCOMPARE = { 53 { 54 (byte) 0xbf, (byte) 0x8b, (byte) 0x45, (byte) 0x30, // 1 n=0 55 (byte) 0xd8, (byte) 0xd2, (byte) 0x46, (byte) 0xdd, 56 (byte) 0x74, (byte) 0xac, (byte) 0x53, (byte) 0xa1, 57 (byte) 0x34, (byte) 0x71, (byte) 0xbb, (byte) 0xa1, 58 (byte) 0x79, (byte) 0x41, (byte) 0xdf, (byte) 0xf7 59 },{ 60 (byte) 0x80, (byte) 0x47, (byte) 0xf8, (byte) 0x24, // 63 n=1 61 (byte) 0x13, (byte) 0xbf, (byte) 0x4c, (byte) 0x0b, 62 (byte) 0x6e, (byte) 0xfb, (byte) 0x6e, (byte) 0xa0, 63 (byte) 0x91, (byte) 0xce, (byte) 0x08, (byte) 0x22, 64 (byte) 0x02, (byte) 0x0d, (byte) 0x2e, (byte) 0xfc 65 },{ 66 (byte) 0x92, (byte) 0xcb, (byte) 0x89, (byte) 0xdf, // 64 n=2 67 (byte) 0x62, (byte) 0xd9, (byte) 0x00, (byte) 0xb3, 68 (byte) 0x50, (byte) 0xd9, (byte) 0x3e, (byte) 0x42, 69 (byte) 0x25, (byte) 0xca, (byte) 0x6f, (byte) 0x08, 70 (byte) 0x1d, (byte) 0x54, (byte) 0x7a, (byte) 0x28 71 },{ 72 (byte) 0x70, (byte) 0x59, (byte) 0xd4, (byte) 0x34, // 65 n=3 73 (byte) 0xa3, (byte) 0xb6, (byte) 0x28, (byte) 0x25, 74 (byte) 0x5c, (byte) 0x3e, (byte) 0xf8, (byte) 0xc8, 75 (byte) 0x92, (byte) 0x83, (byte) 0x9a, (byte) 0xb3, 76 (byte) 0xb9, (byte) 0x1c, (byte) 0x4f, (byte) 0xe6 77 },{ 78 (byte) 0x03, (byte) 0x2f, (byte) 0x1c, (byte) 0x65, // 639 n=4 79 (byte) 0x44, (byte) 0xcc, (byte) 0x88, (byte) 0xf7, 80 (byte) 0x34, (byte) 0xac, (byte) 0xad, (byte) 0xd3, 81 (byte) 0xc4, (byte) 0xe2, (byte) 0x19, (byte) 0x32, 82 (byte) 0xdf, (byte) 0x6c, (byte) 0x88, (byte) 0xfe 83 },{ 84 (byte) 0xe0, (byte) 0x14, (byte) 0xe7, (byte) 0x5d, // 640 n=5 85 (byte) 0xb2, (byte) 0x8b, (byte) 0xe3, (byte) 0xbf, 86 (byte) 0xf7, (byte) 0x6d, (byte) 0xe0, (byte) 0xe7, 87 (byte) 0x35, (byte) 0xc3, (byte) 0x7e, (byte) 0xd0, 88 (byte) 0xe7, (byte) 0xde, (byte) 0x85, (byte) 0x59 89 },{ 90 (byte) 0x8f, (byte) 0xb7, (byte) 0x8c, (byte) 0x50, // 641 n=6 91 (byte) 0xf5, (byte) 0x57, (byte) 0xb1, (byte) 0x56, 92 (byte) 0x84, (byte) 0xae, (byte) 0x07, (byte) 0x4c, 93 (byte) 0x92, (byte) 0xc7, (byte) 0x05, (byte) 0xe3, 94 (byte) 0xd0, (byte) 0xe8, (byte) 0x98, (byte) 0xe8 95 },{ 96 (byte) 0x9c, (byte) 0x59, (byte) 0xea, (byte) 0x66, // 6399 n=7 97 (byte) 0xad, (byte) 0x49, (byte) 0xa5, (byte) 0xd8, 98 (byte) 0x2b, (byte) 0x15, (byte) 0x7f, (byte) 0x3d, 99 (byte) 0x5c, (byte) 0x8a, (byte) 0x4c, (byte) 0x16, 100 (byte) 0x16, (byte) 0x70, (byte) 0x2c, (byte) 0x16 101 },{ 102 (byte) 0x92, (byte) 0x3f, (byte) 0x57, (byte) 0xce, // 6400 n=8 103 (byte) 0x28, (byte) 0x5d, (byte) 0xb2, (byte) 0xd4, 104 (byte) 0x1e, (byte) 0xdc, (byte) 0x86, (byte) 0x04, 105 (byte) 0x50, (byte) 0x92, (byte) 0x2c, (byte) 0x2e, 106 (byte) 0xaf, (byte) 0x15, (byte) 0xef, (byte) 0x93 107 },{ 108 (byte) 0x48, (byte) 0x45, (byte) 0x78, (byte) 0x0a, // 6401 n=9 109 (byte) 0xf1, (byte) 0x9e, (byte) 0x08, (byte) 0x1f, 110 (byte) 0x32, (byte) 0x43, (byte) 0x1d, (byte) 0xb5, 111 (byte) 0x7b, (byte) 0x70, (byte) 0xdf, (byte) 0xe2, 112 (byte) 0xfd, (byte) 0x38, (byte) 0x50, (byte) 0x39 113 },{ 114 (byte) 0xbf, (byte) 0x35, (byte) 0x8f, (byte) 0xbe, // 9999 n=10 115 (byte) 0x88, (byte) 0xc5, (byte) 0x2d, (byte) 0x54, 116 (byte) 0x4e, (byte) 0x3c, (byte) 0x72, (byte) 0xf6, 117 (byte) 0xef, (byte) 0x68, (byte) 0xc3, (byte) 0x0c, 118 (byte) 0xed, (byte) 0xb7, (byte) 0x0a, (byte) 0x36 119 } 120 }; 121 122 /* 123 * array of numbers for which above data were calculated 124 */ 125 private static final int[] LENGTHS = { 1, 63,64,65, 639,640,641, 6399,6400,6401, 9999 }; 126 127 private static final int DIGESTLENGTH = 20; // implementation constants 128 private static final int LENGTH = 100; // 129 130 private static MessageDigest md; 131 132 133 /* 134 * @see TestCase#setUp() 135 */ 136 protected void setUp() throws Exception { 137 super.setUp(); 138 md = MessageDigest.getInstance("SHA-1", "Crypto"); 139 } 140 141 142 /** 143 * test against the "Object clone()" method; 144 * test checks out that clone object has the same state that its origin 145 */ 146 public final void testClone() throws CloneNotSupportedException { 147 148 MessageDigest clone = null; 149 150 byte digest[]; // implementation variables 151 byte digestClone[]; // 152 153 byte[] bytes = new byte[LENGTH]; 154 for (int i = 0; i < bytes.length; i++ ) { 155 bytes[i] = (byte) i; 156 } 157 158 md.update(bytes, 0, LENGTH); 159 clone = (MessageDigest)md.clone(); 160 digest = md.digest(); 161 digestClone = clone.digest(); 162 163 assertEquals("digest.length != digestClone.length :: " + digestClone.length, 164 digest.length, digestClone.length); 165 for (int i = 0; i < digest.length; i++) { 166 assertEquals("digest[i] != digestClone[i] : i=" + i, digest[i], digestClone[i]); 167 } 168 } 169 170 171 /** 172 * test against the "byte[] digest()" method; 173 * it checks out that the method always return array of 20 bytes length 174 */ 175 public final void testDigest01() { 176 177 byte[] bytes = null; 178 179 for ( int i = 0; i < LENGTH; i++ ) { 180 181 byte[] b = new byte[i]; 182 for ( int j = 0; j < b.length; j++ ) { 183 b[j] = (byte) j; 184 } 185 186 md.update(b, 0, b.length); 187 bytes = md.digest(); 188 assertEquals("length of digest != DIGESTLENGTH", bytes.length, DIGESTLENGTH); 189 if ( (i & 1) == 0 ) { 190 md.reset(); 191 } 192 } 193 } 194 195 196 /** 197 * test against "byte[] digest()" method; 198 * it checks out that for given seed arrays 199 * hash arrays returned by the method are the same as in RI 200 */ 201 public final void testDigest02() { 202 203 int i = 0; 204 byte[] results = null; 205 206 for ( int n = 0 ; n < LENGTHS.length; n++ ) { 207 208 for ( int j = 0; j < LENGTHS[n]; j++ ) { 209 md.update((byte)(j +1)); 210 } 211 results = md.digest(); 212 213 for ( int j = 0; j < DIGESTLENGTH; j++ ) { 214 assertEquals("results[j] != HASHTOCOMPARE[i][j] :: n=" + n + " j=" + j + 215 " i=" + i, results[j], HASHTOCOMPARE[i][j]); 216 } 217 i++; 218 } 219 } 220 221 /** 222 * test against the "byte[] digest()" method; 223 * it checks out that "digest()" method resets engine 224 */ 225 public final void testDigest03() { 226 227 byte[] bytes1 = null; 228 byte[] bytes2 = null; 229 230 for ( int i = 1; i < LENGTH; i++ ) { 231 232 byte[] b = new byte[i]; 233 for ( int j = 0; j < b.length; j++ ) { 234 b[j] = (byte) j; 235 } 236 237 md.update(b, 0, b.length); 238 bytes1 = md.digest(); 239 240 md.update(b, 0, b.length); 241 bytes2 = md.digest(); 242 243 assertEquals("bytes1.length != bytes2.length", bytes1.length, bytes2.length); 244 for (int j = 0; j < DIGESTLENGTH ; j++ ) { 245 assertEquals("no equality for i=" +i + " j=" +j, bytes1[j], bytes2[j]); 246 } 247 } 248 } 249 250 251 /** 252 * test against "int digest(byte[], int, int)" method; 253 * it checks out correct throwing exceptions 254 */ 255 public final void testDigestbyteArrayintint01() throws DigestException { 256 257 int offset = 0; 258 int len = 0; 259 260 // IllegalArgumentException if byte[] is null 261 try { 262 md.digest(null, 0, DIGESTLENGTH); 263 fail("digest(null, 0, DIGESTLENGTH) : No IllegalArgumentException"); 264 } catch (IllegalArgumentException e) { 265 } 266 267 // IllegalArgumentException if: (len + offset) <= buf.length 268 for ( offset = -5; offset < 5 ; offset++) { 269 270 try { 271 md.digest(new byte[19], offset, 25); 272 fail("md.digest(new byte[19],offset,25) :: offset=" + offset + 273 " :: No IllegalArgumentException"); 274 } catch (IllegalArgumentException e) { 275 } 276 } 277 for ( len = -5; len < 5 ; len++) { 278 279 try { 280 md.digest(new byte[19], 25, len); 281 fail("md.digest(new byte[19],25,len) :: len=" + len + 282 " :: No IllegalArgumentException"); 283 } catch (IllegalArgumentException e) { 284 } 285 } 286 287 // DigestException if len < DIGESTLENGTH 288 for ( len = DIGESTLENGTH -1; len >=0 ; len-- ) { 289 try { 290 md.digest(new byte[DIGESTLENGTH], 0, len); 291 fail("md.digest(new byte[DIGESTLENGTH], 0, len) :: len=" + 292 len + " :: No DigestException"); 293 } catch (DigestException e) { 294 } 295 } 296 297 // ArrayIndexOutOfBoundsException if offset < 0 298// for ( offset = -5; offset < 0 ; offset++ ) { 299// try { 300// md.digest(new byte[30], offset, DIGESTLENGTH); 301// fail("md.digest(new byte[30], offset, DIGESTLENGTH) :: " + 302// "offset=" + offset + " :: no ArrayIndexOutOfBoundsException"); 303// } catch (ArrayIndexOutOfBoundsException e) { 304// } 305// } 306 } 307 308 309 /** 310 * test agains "int digest(byte[], int, int)" method 311 * it checks out that for given seed arrays 312 * hash arrays returned by the method are the same as in RI 313 */ 314 public final void testDigestbyteArrayintint02() throws DigestException { 315 316 byte[] bytes = null; 317 int i = 0; 318 319 for ( int n = 0 ; n < LENGTHS.length; n++ ) { 320 byte[] results = new byte[DIGESTLENGTH]; 321 322 bytes = new byte[LENGTHS[n]]; 323 for ( int j = 0; j < bytes.length; j++ ) { 324 bytes[j] = (byte)(j +1); 325 } 326 327 md.update(bytes, 0, bytes.length); 328 md.digest(results, 0, DIGESTLENGTH); 329 330 for ( int j = 0; j < DIGESTLENGTH; j++ ) { 331 assertEquals("results[j] != HASHTOCOMPARE[i][j] :: " + " n=" + n + " j=" + 332 j + " i=" + i, results[j], HASHTOCOMPARE[i][j]); 333 } 334 i++; 335 } 336 } 337 338 339 /** 340 * test against "int engineDigest(byte[], int, int)" method 341 * it checks out that engine gets reset after call to the method 342 */ 343 public final void testDigestbyteArrayintint03() throws DigestException { 344 345 byte[] bytes1 = new byte[DIGESTLENGTH]; 346 byte[] bytes2 = new byte[DIGESTLENGTH]; 347 348 for ( int n = 1 ; n < LENGTH; n++ ) { 349 350 byte[] b = new byte[n]; 351 for ( int j = 0; j < b.length; j++ ) { 352 b[j] = (byte) j; 353 } 354 md.update(b, 0, b.length); 355 md.digest(bytes1, 0, DIGESTLENGTH); 356 357 md.update(b, 0, b.length); 358 md.digest(bytes2, 0, DIGESTLENGTH); 359 360 assertEquals("bytes1.length != bytes2.length", bytes1.length, bytes2.length); 361 for (int j = 0; j < DIGESTLENGTH ; j++ ) { 362 assertEquals("no equality for j=" + j, bytes1[j], bytes2[j]); 363 } 364 } 365 } 366 367 368 /** 369 * test against the "int GetDigestLength()" method; 370 * it checks out that the method returns the same value 371 * regardless of previous calls to other methods 372 */ 373 public final void testGetDigestLength() throws DigestException { 374 375 int digestlength = md.getDigestLength(); 376 377 byte[] bytes = new byte[LENGTH]; 378 379 for (int i = 0; i < LENGTH; i++ ) { 380 bytes[i] = (byte)(i&0xFF); 381 } 382 383 for ( int i = 0; i < 8; i++ ) { 384 switch (i) { 385 case 0: md.digest(); 386 break; 387 case 1: md.digest(bytes, 0, bytes.length); 388 break; 389 case 2: md.reset(); 390 break; 391 case 3: md.update(bytes[i]); 392 break; 393 case 4: md.update(bytes, 0, LENGTH); 394 break; 395 case 5: md.update(bytes[i]); 396 break; 397 default: 398 } 399 assertEquals(" !=digestlength", md.getDigestLength(), digestlength); 400 } 401 } 402 403 404 /** 405 * test against the "void engineReset()" method; 406 * it checks out that digests returned after proceeding "engineReset()" 407 * is the same as in case of initial digest 408 */ 409 public final void testReset() { 410 411 byte[] bytes = new byte[LENGTH]; 412 byte[] digest1 = null; 413 byte[] digest2 = null; 414 boolean flag; 415 416 for (int i = 0; i < bytes.length; i++ ) { 417 bytes[i] = (byte)(i&0xFF); 418 } 419 420 digest1 = md.digest(); 421 md.update(bytes, 0, LENGTH); 422 md.reset(); 423 digest2 = md.digest(); 424 425 flag = true; 426 for ( int i = 0; i < digest1.length; i++ ) { 427 flag &= digest1[i] == digest2[i]; 428 } 429 assertTrue("digests are not the same", flag); 430 } 431 432 433 /** 434 * test against the "void update(byte)" method; 435 * it checks out that if one digest is update to its forerunner 436 * the digests are not the same 437 */ 438 public final void testUpdatebyte() { 439 440 boolean flag; 441 byte[] digest1 = null; 442 byte[] digest2 = null; 443 444 for ( int j = 0; j < LENGTH ; j++) { 445 446 byte[] bytes = new byte[j]; 447 448 for (int i = 0; i < bytes.length; i++ ) { 449 bytes[i] = (byte)(i&0xFF); 450 } 451 452 md.update(bytes, 0, bytes.length); 453 digest1 = md.digest(); 454 md.update(bytes, 0, bytes.length); 455 md.update((byte) 0); 456 digest2 = md.digest(); 457 458 flag = true; 459 for ( int i = 0; i < digest1.length; i++ ) { 460 flag &= digest1[i] == digest2[i]; 461 } 462 assertFalse("digests are the same", flag); 463 } 464 } 465 466 467 /** 468 * test against the "void update(byte[], int, int)" method; 469 * it checks out throwing exceptions 470 */ 471 public final void testUpdatebyteArrayintint01() { 472 473 // IllegalArgumentException if byte[] is null 474 try { 475 md.update(null, 0, 0); 476 fail("TESTCASE1 : update(null, 0, 0) :: No IllegalArgumentException"); 477 } catch (IllegalArgumentException e) { 478 } 479 480 // ArrayIndexOutOfBoundsException if len>0 && offset < 0 481// try { 482// md.update(new byte[0], -1, 1); 483// fail("update(new byte[0], -1, 1) : No ArrayIndexOutOfBoundsException"); 484// } catch (ArrayIndexOutOfBoundsException e) { 485// } 486 487 // IllegalArgumentException if (offset + len) >= input.length 488 try { 489 md.update(new byte[1], 0, 2); 490 fail("update(new byte[1], 0, 2) : No IllegalArgumentException"); 491 } catch (IllegalArgumentException e) { 492 } 493 } 494 495 496 /** 497 * test against the "void update(byte[],int,int)" method; 498 * it checks out that two sequential digest, 499 * second is byte array update to first, 500 * are different, provided length of the byte array > 0. 501 */ 502 public final void testUpdatebyteArrayintint02() { 503 504 boolean flag; 505 byte[] digest1 = null; 506 byte[] digest2 = null; 507 508 for ( int j = 0; j < LENGTH ; j++) { 509 510 byte[] bytes = new byte[j]; 511 512 for (int i = 0; i < bytes.length; i++ ) { 513 bytes[i] = (byte)(i&0xFF); 514 } 515 516 md.update((byte) 0); 517 digest1 = md.digest(); 518 md.update((byte) 0); 519 md.update(bytes, 0, bytes.length); 520 digest2 = md.digest(); 521 522 flag = true; 523 for ( int i = 0; i < digest1.length; i++ ) { 524 flag &= digest1[i] == digest2[i]; 525 } 526 if ( j == 0 ) { 527 // no update if byte[] of zero length 528 assertTrue("ATTENTION: digests are not the same", flag); 529 } else { 530 assertFalse("ATTENTION: digests are the same; j=" +j, flag); 531 } 532 } 533 } 534 535 536 /** 537 * test against the "void update(byte[], int, int)" method; 538 * it checks that if the "len" argument <=0 the method just returns with 539 * no affect to MessageDigestImp object (note that such behavior complies with RI). 540 */ 541// public final void testUpdatebyteArrayintint03() { 542// 543// boolean flag; 544// byte[] digest1 = null; 545// byte[] digest2 = null; 546// 547// for ( int j = 0; j < LENGTH ; j++) { 548// 549// byte[] bytes = new byte[j]; 550// 551// for (int i = 0; i < bytes.length; i++ ) { 552// bytes[i] = (byte)(i&0xFF); 553// } 554// 555// md.update(bytes, 0, bytes.length); 556// digest1 = md.digest(); 557// md.update(bytes, 0, bytes.length); 558// md.update(new byte[1], 0, -1); 559// md.update(new byte[1], 0, 0); 560// digest2 = md.digest(); 561// 562// assertTrue("digest's lengths are different : length1=" + 563// digest1.length + " length2=" + digest2.length, 564// digest1.length == digest2.length ); 565// 566// for ( int i = 0; i < digest1.length ; i++ ) { 567// assertTrue("different digests : i=" +i + 568// " digest1[i]=" + digest1[i] + " digest2[i]=" + digest2[i], 569// digest1[i] == digest2[i] ); 570// } 571// } 572// } 573 574 575 public static Test suite() { 576 return new TestSuite(SHA1_MessageDigestTest.class); 577 } 578 579 } 580