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 Boris V. Kuznetsov 20* @version $Revision$ 21*/ 22 23package org.apache.harmony.security.tests.java.security; 24 25import dalvik.annotation.KnownFailure; 26 27import java.security.InvalidParameterException; 28import java.security.NoSuchAlgorithmException; 29import java.security.Provider; 30import java.security.Security; 31import java.security.Signature; 32import java.security.InvalidAlgorithmParameterException; 33import java.security.InvalidKeyException; 34import java.security.Key; 35import java.security.PrivateKey; 36import java.security.PublicKey; 37import java.security.SecureRandom; 38import java.security.SignatureException; 39import java.security.SignatureSpi; 40import java.security.cert.Certificate; 41import java.security.spec.AlgorithmParameterSpec; 42 43import org.apache.harmony.security.tests.support.MySignature1; 44 45import junit.framework.TestCase; 46 47/** 48 * Tests for <code>Signature</code> constructor and methods 49 * 50 */ 51public class SignatureTest extends TestCase { 52 53 /* 54 * Class under test for Signature(String) 55 */ 56 public void testConstructor() { 57 String [] algorithms = { "SHA256WITHRSA", "NONEWITHDSA", "SHA384WITHRSA", 58 "MD5ANDSHA1WITHRSA", "SHA512WITHRSA", 59 "SHA1WITHRSA", "SHA1WITHDSA", "MD5WITHRSA" }; 60 for (int i = 0; i < algorithms.length; i ++) { 61 MySignature1 s = new MySignature1(algorithms[i]); 62 assertEquals(algorithms[i],s.getAlgorithm()); 63 assertNull(s.getProvider()); 64 assertEquals(0, s.getState()); 65 } 66 67 MySignature1 s1 = new MySignature1(null); 68 assertNull(s1.getAlgorithm()); 69 assertNull(s1.getProvider()); 70 assertEquals(0, s1.getState()); 71 72 MySignature1 s2 = new MySignature1("ABCD@#&^%$)(*&"); 73 assertEquals("ABCD@#&^%$)(*&", s2.getAlgorithm()); 74 assertNull(s2.getProvider()); 75 assertEquals(0, s2.getState()); 76 } 77 78 /* 79 * Class under test for Object clone() 80 */ 81 public void testClone() { 82 MySignature1 s = new MySignature1("ABC"); 83 try { 84 s.clone(); 85 fail("No expected CloneNotSupportedException"); 86 } catch (CloneNotSupportedException e) { 87 } 88 89 MySignature sc = new MySignature(); 90 try { 91 sc.clone(); 92 } catch (CloneNotSupportedException e) { 93 fail("unexpected exception: " + e); 94 } 95 96 } 97 98 public void testGetProvider() { 99 MySignature1 s = new MySignature1("ABC"); 100 101 assertEquals("state", MySignature1.UNINITIALIZED, s.getState()); 102 assertNull("provider", s.getProvider()); 103 } 104 105 public void testGetAlgorithm() { 106 MySignature1 s = new MySignature1("ABC"); 107 108 assertEquals("state", MySignature1.UNINITIALIZED, s.getState()); 109 assertEquals("algorithm", "ABC", s.getAlgorithm()); 110 } 111 112 /* 113 * Class under test for void initVerify(PublicKey) 114 */ 115 public void testInitVerifyPublicKey() throws InvalidKeyException { 116 MySignature1 s = new MySignature1("ABC"); 117 118 s.initVerify(new MyPublicKey()); 119 assertEquals("state", MySignature1.VERIFY, s.getState()); 120 assertTrue("initVerify() failed", s.runEngineInitVerify); 121 122 try { 123 Signature sig = getTestSignature(); 124 sig.initVerify((PublicKey)null); 125 } catch (InvalidKeyException e) { 126 // ok 127 } catch (NoSuchAlgorithmException e) { 128 fail("unexpected : " + e); 129 } 130 } 131 132 /* 133 * Class under test for void initVerify(Certificate) 134 */ 135 public void testInitVerifyCertificate() throws InvalidKeyException { 136 MySignature1 s = new MySignature1("ABC"); 137 138 s.initVerify(new MyCertificate()); 139 assertEquals("state", MySignature1.VERIFY, s.getState()); 140 assertTrue("initVerify() failed", s.runEngineInitVerify); 141 142 try { 143 Signature sig = getTestSignature(); 144 sig.initVerify(new MyCertificate()); 145 fail("expected InvalidKeyException"); 146 } catch (InvalidKeyException e) { 147 // ok 148 } catch (NoSuchAlgorithmException e) { 149 fail("unexpected : " + e); 150 } 151 } 152 153 /* 154 * Class under test for void initSign(PrivateKey) 155 */ 156 public void testInitSignPrivateKey() throws InvalidKeyException { 157 MySignature1 s = new MySignature1("ABC"); 158 159 s.initSign(new MyPrivateKey()); 160 assertEquals("state", MySignature1.SIGN, s.getState()); 161 assertTrue("initSign() failed", s.runEngineInitSign); 162 163 try { 164 Signature signature = getTestSignature(); 165 signature.initSign(null); 166 fail("expected InvalidKeyException"); 167 } catch (InvalidKeyException e) { 168 // ok 169 } catch (NoSuchAlgorithmException e) { 170 fail("unexpected: " + e); 171 } 172 } 173 174 private Signature getTestSignature() throws NoSuchAlgorithmException { 175 Provider provider = new MyProvider("TestProvider", 1.0, "Test Provider", "Signature.ABC", MySignature.class.getName()); 176 Security.insertProviderAt(provider, 1); 177 178 try { 179 return Signature.getInstance("ABC"); 180 } 181 finally { 182 Security.removeProvider("TestProvider"); 183 } 184 185 } 186 187 /* 188 * Class under test for void initSign(PrivateKey, SecureRandom) 189 */ 190 public void testInitSignPrivateKeySecureRandom() throws InvalidKeyException { 191 MySignature1 s = new MySignature1("ABC"); 192 193 s.initSign(new MyPrivateKey(), new SecureRandom()); 194 assertEquals("state", MySignature1.SIGN, s.getState()); 195 assertTrue("initSign() failed", s.runEngineInitSign); 196 197 try { 198 Signature sig = getTestSignature(); 199 sig.initSign(null, null); 200 fail("expected InvalidKeyException"); 201 } catch (InvalidKeyException e) { 202 // ok 203 } catch (NoSuchAlgorithmException e) { 204 fail("unexpected : " + e); 205 } 206 } 207 208 /* 209 * Class under test for byte[] sign() 210 */ 211 public void testSign() throws Exception { 212 MySignature1 s = new MySignature1("ABC"); 213 try { 214 s.sign(); 215 fail("No expected SignatureException"); 216 } catch (SignatureException e) { 217 } 218 219 s.initVerify(new MyPublicKey()); 220 221 try { 222 s.sign(); 223 fail("No expected SignatureException"); 224 } catch (SignatureException e) { 225 } 226 227 s.initSign(new MyPrivateKey()); 228 s.sign(); 229 assertEquals("state", MySignature1.SIGN, s.getState()); 230 assertTrue("sign() failed", s.runEngineSign); 231 } 232 233 /* 234 * Class under test for sign(byte[], offset, len) 235 */ 236 public void testSignbyteintint() throws Exception { 237 MySignature1 s = new MySignature1("ABC"); 238 byte[] outbuf = new byte [10]; 239 try { 240 s.sign(outbuf, 0, outbuf.length); 241 fail("No expected SignatureException"); 242 } catch (SignatureException e) { 243 } 244 245 s.initVerify(new MyPublicKey()); 246 247 try { 248 s.sign(outbuf, 0, outbuf.length); 249 fail("No expected SignatureException"); 250 } catch (SignatureException e) { 251 } 252 253 s.initSign(new MyPrivateKey()); 254 assertEquals(s.getBufferLength(), s.sign(outbuf, 0, outbuf.length)); 255 assertEquals("state", MySignature1.SIGN, s.getState()); 256 assertTrue("sign() failed", s.runEngineSign); 257 258 try { 259 s.initSign(new MyPrivateKey()); 260 s.sign(outbuf, outbuf.length, 0); 261 fail("expected SignatureException"); 262 } catch (SignatureException e) { 263 // ok 264 } 265 266 try { 267 s.initSign(new MyPrivateKey()); 268 s.sign(outbuf, outbuf.length, 3); 269 fail("expected IllegalArgumentException"); 270 } catch (IllegalArgumentException e) { 271 // ok 272 } 273 274 } 275 276 277 /* 278 * Class under test for boolean verify(byte[]) 279 */ 280 public void testVerifybyteArray() throws Exception { 281 MySignature1 s = new MySignature1("ABC"); 282 byte[] b = {1, 2, 3, 4}; 283 try { 284 s.verify(b); 285 fail("No expected SignatureException"); 286 } catch (SignatureException e) { 287 } 288 289 s.initSign(new MyPrivateKey()); 290 try { 291 s.verify(b); 292 fail("No expected SignatureException"); 293 } catch (SignatureException e) { 294 } 295 296 s.initVerify(new MyPublicKey()); 297 s.verify(b); 298 assertEquals("state", MySignature1.VERIFY, s.getState()); 299 assertTrue("verify() failed", s.runEngineVerify); 300 } 301 302 /* 303 * Class under test for boolean verify(byte[], int, int) 304 */ 305 public void testVerifybyteArrayintint() throws Exception { 306 MySignature1 s = new MySignature1("ABC"); 307 byte[] b = {1, 2, 3, 4}; 308 try { 309 s.verify(b, 0, 3); 310 fail("No expected SignatureException"); 311 } catch (SignatureException e) { 312 } 313 314 s.initSign(new MyPrivateKey()); 315 316 try { 317 s.verify(b, 0, 3); 318 fail("No expected SignatureException"); 319 } catch (SignatureException e) { 320 } 321 322 s.initVerify(new MyPublicKey()); 323 324 try { 325 s.verify(b, 0, 5); 326 fail("No expected IllegalArgumentException"); 327 } catch (IllegalArgumentException e) { 328 } 329 330 s.verify(b, 0, 3); 331 assertEquals("state", MySignature1.VERIFY, s.getState()); 332 assertTrue("verify() failed", s.runEngineVerify); 333 } 334 335 /* 336 * Class under test for void update(byte) 337 */ 338 public void testUpdatebyte() throws Exception { 339 MySignature1 s = new MySignature1("ABC"); 340 try { 341 s.update((byte)1); 342 fail("No expected SignatureException"); 343 } catch (SignatureException e) { 344 } 345 346 s.initVerify(new MyPublicKey()); 347 s.update((byte) 1); 348 s.initSign(new MyPrivateKey()); 349 s.update((byte) 1); 350 351 assertEquals("state", MySignature1.SIGN, s.getState()); 352 assertTrue("update() failed", s.runEngineUpdate1); 353 354 try { 355 Signature sig = getTestSignature(); 356 sig.update((byte) 42); 357 fail("expected SignatureException"); 358 } catch (SignatureException e) { 359 // ok 360 } 361 } 362 363 /* 364 * Class under test for void update(byte[]) 365 */ 366 public void testUpdatebyteArray() throws Exception { 367 MySignature1 s = new MySignature1("ABC"); 368 byte[] b = {1, 2, 3, 4}; 369 try { 370 s.update(b); 371 fail("No expected SignatureException"); 372 } catch (SignatureException e) { 373 } 374 375 s.initVerify(new MyPublicKey()); 376 s.update(b); 377 s.initSign(new MyPrivateKey()); 378 s.update(b); 379 380 assertEquals("state", MySignature1.SIGN, s.getState()); 381 assertTrue("update() failed", s.runEngineUpdate2); 382 383 try { 384 Signature sig = getTestSignature(); 385 sig.update(b); 386 fail("expected SignatureException"); 387 } catch (SignatureException e) { 388 // ok 389 } 390 391 try { 392 Signature sig = getTestSignature(); 393 sig.update((byte[])null); 394 fail("expected NullPointerException"); 395 } catch (SignatureException e) { 396 // ok 397 } catch (NullPointerException e) { 398 // ok 399 } 400 } 401 402 /* 403 * Class under test for void update(byte[], int, int) 404 */ 405 public void testUpdatebyteArrayintint() throws Exception { 406 MySignature1 s = new MySignature1("ABC"); 407 byte[] b = {1, 2, 3, 4}; 408 try { 409 s.update(b, 0, 3); 410 fail("No expected SignatureException"); 411 } catch (SignatureException e) { 412 } 413 414 s.initVerify(new MyPublicKey()); 415 s.update(b, 0, 3); 416 s.initSign(new MyPrivateKey()); 417 s.update(b, 0, 3); 418 419 assertEquals("state", MySignature1.SIGN, s.getState()); 420 assertTrue("update() failed", s.runEngineUpdate2); 421 422 try { 423 s.update(b, 3, 0); 424 fail("expected IllegalArgumentException"); 425 } catch (IllegalArgumentException e) { 426 // ok 427 } 428 429 try { 430 s.update(b, 0, b.length + 1); 431 fail("expected IllegalArgumentException"); 432 } catch (IllegalArgumentException e) { 433 // ok 434 } 435 436 try { 437 s.update(b, -1, b.length); 438 fail("expected IllegalArgumentException"); 439 } catch (IllegalArgumentException e) { 440 // ok 441 } 442 443 } 444 445 /* 446 * Class under test for void update(byte[], int, int) 447 */ 448 @KnownFailure("Android throws IllegalArgumentException, RI throws NullpointerException") 449 public void testUpdatebyteArrayintint2() throws Exception { 450 MySignature1 s = new MySignature1("ABC"); 451 byte[] b = {1, 2, 3, 4}; 452 453 s.initVerify(new MyPublicKey()); 454 s.update(b, 0, 3); 455 s.initSign(new MyPrivateKey()); 456 s.update(b, 0, 3); 457 458 assertEquals("state", MySignature1.SIGN, s.getState()); 459 assertTrue("update() failed", s.runEngineUpdate2); 460 461 try { 462 s.update(null, 0, 3); 463 fail("NullPointerException wasn't thrown"); 464 } catch (NullPointerException npe) { 465 // ok 466 } 467 } 468 469 470 /* 471 * Class under test for void setParameter(String, Object) 472 */ 473 @SuppressWarnings("deprecation") 474 public void testSetParameterStringObject() { 475 MySignature1 s = new MySignature1("ABC"); 476 s.setParameter("aaa", new Object()); 477 478 try { 479 Signature sig = getTestSignature(); 480 sig.setParameter("TestParam", new Integer(42)); 481 fail("expected InvalidParameterException"); 482 } catch (InvalidParameterException e) { 483 // expected 484 } catch (NoSuchAlgorithmException e) { 485 fail("unexpected: " + e); 486 } 487 } 488 489 /* 490 * Class under test for void setParameter(AlgorithmParameterSpec) 491 */ 492 public void testSetParameterAlgorithmParameterSpec() throws InvalidAlgorithmParameterException { 493 MySignature1 s = new MySignature1("ABC"); 494 try { 495 s.setParameter((java.security.spec.AlgorithmParameterSpec)null); 496 fail("No expected UnsupportedOperationException"); 497 } catch (UnsupportedOperationException e){ 498 } 499 500 try { 501 Signature sig = getTestSignature(); 502 sig.setParameter(new AlgorithmParameterSpec() {}); 503 } catch (InvalidAlgorithmParameterException e) { 504 fail("unexpected: " + e); 505 } catch (NoSuchAlgorithmException e) { 506 fail("unexpected: " + e); 507 } 508 } 509 510 @SuppressWarnings("deprecation") 511 public void testGetParameter() { 512 MySignature1 s = new MySignature1("ABC"); 513 s.getParameter("aaa"); 514 515 try { 516 MySignature se = new MySignature(); 517 se.getParameter("test"); 518 } catch (InvalidParameterException e) { 519 // ok 520 } 521 522 } 523 524 // https://android-review.googlesource.com/#/c/309105/ 525 // http://b/33383388 526 // getCurrentSpi throws a NPE on a Signature that was obtained via a provider that has that 527 // algorithm registered for a SignatureSpi. 528 public void testSignature_getCurrentSpi_Success() throws Exception { 529 Provider provider = new MyProvider( 530 "TestProvider", 1.0, "Test Provider", "Signature.ABC", 531 MySignatureSpi.class.getName()); 532 Signature signature = Signature.getInstance("ABC", provider); 533 assertNotNull(signature.getCurrentSpi()); 534 assertEquals(MySignatureSpi.class, signature.getCurrentSpi().getClass()); 535 } 536 537 private class MyKey implements Key { 538 public String getFormat() { 539 return "123"; 540 } 541 public byte[] getEncoded() { 542 return null; 543 } 544 public String getAlgorithm() { 545 return "aaa"; 546 } 547 } 548 549 private class MyPublicKey extends MyKey implements PublicKey {} 550 551 private class MyPrivateKey extends MyKey implements PrivateKey {} 552 553 private class MyCertificate extends java.security.cert.Certificate { 554 public MyCertificate() { 555 super("MyCertificateType"); 556 } 557 558 public PublicKey getPublicKey() { 559 return new MyPublicKey(); 560 } 561 562 public byte[] getEncoded() { 563 return null; 564 } 565 public void verify(PublicKey key) {} 566 567 public void verify(PublicKey key, String sigProvider) {} 568 569 public String toString() { 570 return "MyCertificate"; 571 } 572 } 573 574 @SuppressWarnings("unused") 575 // Needs to be public as this is checked by the provider class when providing an instance of 576 // a class 577 // There is a lot of code duplication, or better said, signature duplication with respect to 578 // MySignatureSpi. However, as for the test to check the desired functionality this class 579 // must extend from Signature and MySignatureSpi must extend from SignatureSpi. Then there is 580 // no way to avoid duplication other than delegation, but delegation would require to repeat 581 // all method signatures once more. 582 public static class MySignature extends Signature implements Cloneable { 583 584 public MySignature() { 585 super("TestSignature"); 586 } 587 588 @Override 589 protected Object engineGetParameter(String param) 590 throws InvalidParameterException { 591 throw new InvalidParameterException(); 592 } 593 594 @Override 595 protected void engineInitSign(PrivateKey privateKey) 596 throws InvalidKeyException { 597 throw new InvalidKeyException(); 598 } 599 600 @Override 601 protected void engineInitVerify(PublicKey publicKey) 602 throws InvalidKeyException { 603 throw new InvalidKeyException(); 604 } 605 606 @Override 607 protected void engineSetParameter(String param, Object value) 608 throws InvalidParameterException { 609 throw new InvalidParameterException(); 610 } 611 612 @Override 613 protected byte[] engineSign() throws SignatureException { 614 return null; 615 } 616 617 @Override 618 protected void engineUpdate(byte b) throws SignatureException { 619 throw new SignatureException(); 620 } 621 622 @Override 623 protected void engineUpdate(byte[] b, int off, int len) 624 throws SignatureException { 625 626 } 627 628 @Override 629 protected boolean engineVerify(byte[] sigBytes) 630 throws SignatureException { 631 return false; 632 } 633 634 @Override 635 protected void engineSetParameter(AlgorithmParameterSpec params) 636 throws InvalidAlgorithmParameterException { 637 if (params == null) { 638 throw new InvalidAlgorithmParameterException(); 639 } 640 } 641 } 642 643 @SuppressWarnings("unused") 644 // Needs to be public as this is checked by the provider class when providing an instance of 645 // a class 646 public static class MySignatureSpi extends SignatureSpi implements Cloneable { 647 648 @Override 649 protected Object engineGetParameter(String param) 650 throws InvalidParameterException { 651 throw new InvalidParameterException(); 652 } 653 654 @Override 655 protected void engineInitSign(PrivateKey privateKey) 656 throws InvalidKeyException { 657 throw new InvalidKeyException(); 658 } 659 660 @Override 661 protected void engineInitVerify(PublicKey publicKey) 662 throws InvalidKeyException { 663 throw new InvalidKeyException(); 664 } 665 666 @Override 667 protected void engineSetParameter(String param, Object value) 668 throws InvalidParameterException { 669 throw new InvalidParameterException(); 670 } 671 672 @Override 673 protected byte[] engineSign() throws SignatureException { 674 return null; 675 } 676 677 @Override 678 protected void engineUpdate(byte b) throws SignatureException { 679 throw new SignatureException(); 680 } 681 682 @Override 683 protected void engineUpdate(byte[] b, int off, int len) 684 throws SignatureException { 685 686 } 687 688 @Override 689 protected boolean engineVerify(byte[] sigBytes) 690 throws SignatureException { 691 return false; 692 } 693 694 @Override 695 protected void engineSetParameter(AlgorithmParameterSpec params) 696 throws InvalidAlgorithmParameterException { 697 if (params == null) { 698 throw new InvalidAlgorithmParameterException(); 699 } 700 } 701 } 702 703 private class MyProvider extends Provider { 704 705 protected MyProvider(String name, double version, String info, String signame, String className) { 706 super(name, version, info); 707 put(signame, className); 708 } 709 710 } 711} 712