/* * Licensed to the Apache Software Foundation (ASF) under one or more * contributor license agreements. See the NOTICE file distributed with * this work for additional information regarding copyright ownership. * The ASF licenses this file to You under the Apache License, Version 2.0 * (the "License"); you may not use this file except in compliance with * the License. You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. */ package org.apache.harmony.security.tests.java.security; import dalvik.annotation.TestTargetClass; import dalvik.annotation.TestTargetNew; import dalvik.annotation.TestTargets; import dalvik.annotation.TestLevel; import java.math.BigInteger; import java.nio.ByteBuffer; import java.security.AlgorithmParameters; import java.security.InvalidKeyException; import java.security.InvalidParameterException; import java.security.KeyPair; import java.security.KeyPairGenerator; import java.security.PrivateKey; import java.security.Provider; import java.security.PublicKey; import java.security.SecureRandom; import java.security.Security; import java.security.Signature; import java.security.SignatureException; import java.security.cert.Certificate; import java.security.spec.DSAParameterSpec; import java.util.HashSet; import java.util.Locale; import java.util.Set; import java.security.NoSuchAlgorithmException; import java.security.NoSuchProviderException; @TestTargetClass(Signature.class) public class Signature2Test extends junit.framework.TestCase { private static final String MESSAGE = "abc"; static KeyPair dsaKeys; static KeyPair rsaKeys; static { try { KeyPairGenerator keyGen = KeyPairGenerator.getInstance("DSA"); keyGen.initialize(1024); dsaKeys = keyGen.generateKeyPair(); KeyPairGenerator keyGen2 = KeyPairGenerator.getInstance("RSA"); keyGen2.initialize(1024); rsaKeys = keyGen2.generateKeyPair(); } catch (Exception e) { fail(e.toString()); } } /** * @tests java.security.Signature#clone() */ @TestTargetNew( level = TestLevel.PARTIAL_COMPLETE, notes = "CloneNotSupportedException checking was tested", method = "clone", args = {} ) public void test_clone() throws Exception { Signature s = Signature.getInstance("DSA"); try { s.clone(); fail("A Signature may not be cloneable"); } catch (CloneNotSupportedException e) { // Expected - a Signature may not be cloneable } } /** * @tests java.security.Signature#getAlgorithm() */ @TestTargetNew( level = TestLevel.COMPLETE, notes = "", method = "getAlgorithm", args = {} ) public void test_getAlgorithm() throws Exception { String alg = Signature.getInstance("DSA").getAlgorithm(); assertTrue("getAlgorithm did not get DSA (" + alg + ")", alg .indexOf("DSA") != -1); } /** * @tests java.security.Signature#getInstance(java.lang.String) */ @TestTargetNew( level = TestLevel.COMPLETE, notes = "", method = "getInstance", args = {java.lang.String.class} ) public void test_getInstanceLjava_lang_String() { try { Signature.getInstance("DSA"); } catch (Exception e) { fail("Unexpected exception for DSA algorithm"); } try { Signature.getInstance("SHA-256"); fail("NoSuchAlgorithmException was not thrown for unavailable algorithm"); } catch (NoSuchAlgorithmException e) { //expected } } /** * @tests java.security.Signature#getInstance(java.lang.String, * java.security.Provider) */ @TestTargetNew( level = TestLevel.COMPLETE, notes = "", method = "getInstance", args = {java.lang.String.class, java.security.Provider.class} ) public void test_getInstanceLjava_lang_StringLjava_lang_String_java_security_Provider() throws Exception { Provider[] providers = Security.getProviders("Signature.DSA"); for (int i = 0; i < providers.length; i++) { Signature signature = Signature.getInstance("DSA", providers[i]); assertEquals("DSA", signature.getAlgorithm()); assertEquals(providers[i], signature.getProvider()); } try { Signature.getInstance((String) null, (Provider) null); fail("NullPointerException expected"); } catch (NullPointerException e) { // expected } try { Signature.getInstance("DSA", (Provider) null); fail("IllegalArgumentException expected"); } catch (IllegalArgumentException e) { // expected } try { Signature.getInstance((String) null, providers[0]); fail("NullPointerException expected"); } catch (NullPointerException e) { // expected } try { Signature.getInstance("SHA-256", providers[0]); fail("NoSuchAlgorithmException expected"); } catch (NoSuchAlgorithmException e) { // expected } } /** * @tests java.security.Signature#getInstance(java.lang.String, * java.lang.String) */ @TestTargetNew( level = TestLevel.COMPLETE, notes = "", method = "getInstance", args = {java.lang.String.class, java.lang.String.class} ) public void test_getInstanceLjava_lang_StringLjava_lang_String() throws Exception { Provider[] providers = Security.getProviders("Signature.DSA"); for (int i = 0; i < providers.length; i++) { Signature.getInstance("DSA", providers[i].getName()); }// end for try { Signature.getInstance("SHA-256", providers[0].getName()); fail("NoSuchAlgorithmException expected"); } catch (NoSuchAlgorithmException e) { // expected } Provider[] pp = Security.getProviders(); for (int i = 0; i < pp.length; i++) { try { Signature.getInstance("DSA", pp[i].toString()); fail("NoSuchProviderException expected"); } catch (NoSuchProviderException e) { // expected } } String[] sp = {null, ""}; for (int i = 0; i < sp.length; i++) { try { Signature.getInstance("DSA", sp[i]); fail("IllegalArgumentException was not throw for " + sp[i]); } catch (IllegalArgumentException e) { // expected } } } /** * @tests java.security.Signature#getParameters() */ @TestTargetNew( level = TestLevel.COMPLETE, notes = "", method = "getParameters", args = {} ) public void test_getParameters() throws Exception { Signature sig = Signature.getInstance("DSA"); try { sig.getParameters(); } catch (UnsupportedOperationException e) { // Could be that the operation is not supported } try { MySignature sig2 = new MySignature("test"); sig2.getParameters(); fail("expected UnsupportedOperationException"); } catch (UnsupportedOperationException e) { // ok } try { MySignature sig2 = new MySignature("ABC"); sig2.getParameters(); } catch (UnsupportedOperationException e) { fail("unexpected: " + e); } } /** * @tests java.security.Signature#getParameter(java.lang.String) */ @TestTargetNew( level = TestLevel.PARTIAL_COMPLETE, notes = "Just exception case was tested", method = "getParameter", args = {java.lang.String.class} ) @SuppressWarnings("deprecation") public void test_getParameterLjava_lang_String() throws Exception { Signature sig = Signature.getInstance("DSA"); try { sig.getParameter("r"); sig.getParameter("s"); } catch (UnsupportedOperationException e) { } } /** * @tests java.security.Signature#getProvider() */ @TestTargetNew( level = TestLevel.COMPLETE, notes = "", method = "getProvider", args = {} ) public void test_getProvider() throws Exception { Provider p = Signature.getInstance("DSA").getProvider(); assertNotNull("provider is null", p); } /** * @tests java.security.Signature#initSign(java.security.PrivateKey) */ @TestTargetNew( level = TestLevel.COMPLETE, notes = "", method = "initSign", args = {java.security.PrivateKey.class} ) public void test_initSignLjava_security_PrivateKey() throws Exception { try { Signature.getInstance("DSA").initSign(dsaKeys.getPrivate()); } catch (InvalidKeyException e) { fail("unexpected: " + e); } try { Signature.getInstance("DSA").initSign(rsaKeys.getPrivate()); fail("expected InvalidKeyException"); } catch (InvalidKeyException e) { // ok } } @TestTargetNew ( level=TestLevel.COMPLETE, method="initSign", args={PrivateKey.class, SecureRandom.class} ) public void test_initSignLjava_security_PrivateKeyLjava_security_SecureRandom() { try { Signature sig = Signature.getInstance("DSA"); sig.initSign(dsaKeys.getPrivate(), new SecureRandom()); } catch (NoSuchAlgorithmException e) { fail("unexpected: " + e); } catch (InvalidKeyException e) { fail("unexpected: " + e); } try { Signature sig = Signature.getInstance("DSA"); sig.initSign(rsaKeys.getPrivate(), new SecureRandom()); fail("expected InvalidKeyException"); } catch (InvalidKeyException e) { // ok } catch (NoSuchAlgorithmException e) { fail("unexpected: " + e); } } /** * @tests java.security.Signature#initVerify(java.security.PublicKey) */ @TestTargetNew( level = TestLevel.COMPLETE, notes = "", method = "initVerify", args = {java.security.PublicKey.class} ) public void test_initVerifyLjava_security_PublicKey() throws Exception { Signature.getInstance("DSA").initVerify(dsaKeys.getPublic()); try { Signature.getInstance("DSA").initVerify(rsaKeys.getPublic()); fail("expected InvalidKeyException"); } catch (InvalidKeyException e) { // ok } } /** * @tests java.security.Signature#initVerify(java.security.cert.Certificate) */ @TestTargetNew( level = TestLevel.PARTIAL, notes = "InvalidKeyException checking missed", method = "initVerify", args = {java.security.cert.Certificate.class} ) public void test_initVerifyLjava_security_Certificate() throws Exception { Provider p = new MyProvider(); p.put("DSA", "tests.java.security.support.cert.MyCertificate$1"); Provider myProvider = new MyProvider(); Security.addProvider(myProvider); try { Provider[] pp = Security.getProviders(); if (pp == null) { return; } try { Signature.getInstance("DSA").initVerify((Certificate) null); fail("NullPointerException expected"); } catch (NullPointerException e) { // fail } } finally { Security.removeProvider(myProvider.getName()); } } /** * @tests java.security.Signature#setParameter(java.lang.String, * java.lang.Object) */ @TestTargetNew( level = TestLevel.PARTIAL, notes = "Just exception case was tested", method = "setParameter", args = {java.lang.String.class, java.lang.Object.class} ) @SuppressWarnings("deprecation") public void test_setParameterLjava_lang_StringLjava_lang_Object() throws Exception { Signature sig = Signature.getInstance("DSA"); try { sig.setParameter("r", BigInteger.ONE); sig.setParameter("s", BigInteger.ONE); } catch (InvalidParameterException e) { // Could be that it's an invalid param for the found algorithm } catch (UnsupportedOperationException e) { // Could be that the operation is not supported } } /** * @tests java.security.Signature#setParameter(java.security.spec.AlgorithmParameterSpec) */ @TestTargetNew( level = TestLevel.PARTIAL, notes = "Just exception case was tested", method = "setParameter", args = {java.security.spec.AlgorithmParameterSpec.class} ) public void test_setParameterLjava_security_spec_AlgorithmParameterSpec() throws Exception { Signature sig = Signature.getInstance("DSA"); try { DSAParameterSpec spec = new DSAParameterSpec(BigInteger.ONE, BigInteger.ONE, BigInteger.ONE); sig.setParameter(spec); } catch (InvalidParameterException e) { // Could be that it's an invalid param for the found algorithm } catch (UnsupportedOperationException e) { // Could be that the operation is not supported } } /** * @tests java.security.Signature#sign() */ @TestTargetNew( level = TestLevel.SUFFICIENT, notes = "Verification of returned value missed. SignatureException checking missed.", method = "sign", args = {} ) public void test_sign() throws Exception { Signature sig = Signature.getInstance("DSA"); sig.initSign(dsaKeys.getPrivate()); sig.update(MESSAGE.getBytes()); sig.sign(); } /** * @tests java.security.Signature#toString() */ @TestTargetNew( level = TestLevel.COMPLETE, notes = "", method = "toString", args = {} ) public void test_toString() throws Exception { String str = Signature.getInstance("DSA").toString(); assertNotNull("toString is null", str); } /** * @tests java.security.Signature#update(byte[]) */ @TestTargetNew( level = TestLevel.COMPLETE, notes = "SignatureException checking missed", method = "update", args = {byte[].class} ) public void test_update$B() throws Exception { Signature sig = Signature.getInstance("DSA"); sig.initSign(dsaKeys.getPrivate()); byte[] bytes = MESSAGE.getBytes(); sig.update(bytes); try { Signature sig2 = Signature.getInstance("DSA"); sig2.update(MESSAGE.getBytes()); fail("expected SignatureException"); } catch (SignatureException e) { // ok } } /** * @tests java.security.Signature#update(byte[], int, int) */ @TestTargetNew( level = TestLevel.PARTIAL, notes = "SignatureException checking missed. Verification of different values off and len missed.", method = "update", args = {byte[].class, int.class, int.class} ) public void test_update$BII() throws Exception { Signature sig = Signature.getInstance("DSA"); byte[] bytes = MESSAGE.getBytes(); try { sig.update(bytes, 0, bytes.length); fail("expected SignatureException"); } catch (SignatureException e) { // ok; } sig.initSign(dsaKeys.getPrivate()); sig.update(bytes, 0, bytes.length); sig.update(bytes, bytes.length - 2, 2); try { sig.update(bytes, bytes.length -3, 4); fail("expected IllegalArgumentException"); } catch (IllegalArgumentException e) { // ok } try { sig.update(null, 0, 5); fail("expected IllegalArgumentException"); } catch (IllegalArgumentException e) { // ok } } /** * @tests java.security.Signature#update(byte) */ @TestTargetNew( level = TestLevel.PARTIAL, notes = "SignatureException checking missed", method = "update", args = {byte.class} ) public void test_updateB() throws Exception { Signature sig = Signature.getInstance("DSA"); sig.initSign(dsaKeys.getPrivate()); sig.update(MESSAGE.getBytes()[0]); } /** * @tests java.security.Signature#update(ByteBuffer data) */ @TestTargetNew( level = TestLevel.COMPLETE, notes = "", method = "update", args = {java.nio.ByteBuffer.class} ) public void test_updateLjava_nio_ByteBuffer() throws Exception { Signature sig = Signature.getInstance("DSA"); ByteBuffer buffer = ByteBuffer.allocate(10); try { sig.update(buffer); fail("SignatureException expected"); } catch (SignatureException e) { // expected } try { sig.initSign(dsaKeys.getPrivate()); sig.update(buffer); } catch (Exception e) { fail("Unexpected exception " + e.getMessage()); } } /** * @tests java.security.Signature#verify(byte[]) */ @TestTargetNew( level = TestLevel.COMPLETE, notes = "", method = "verify", args = {byte[].class} ) public void test_verify$B() throws Exception { Signature sig = Signature.getInstance("DSA"); try { sig.verify(new byte[] { 0,1,2,3 }); fail("expected SignatureException"); } catch (SignatureException e) { // ok } sig.initSign(dsaKeys.getPrivate()); sig.update(MESSAGE.getBytes()); byte[] signature = sig.sign(); sig.initVerify(dsaKeys.getPublic()); sig.update(MESSAGE.getBytes()); assertTrue("Sign/Verify does not pass", sig.verify(signature)); } /** * @tests java.security.Signature#verify(byte[], int, int) */ @TestTargetNew( level = TestLevel.COMPLETE, notes = "", method = "verify", args = {byte[].class, int.class, int.class} ) public void test_verify$BII() throws Exception { Signature sig = Signature.getInstance("DSA"); sig.initSign(dsaKeys.getPrivate()); sig.update(MESSAGE.getBytes()); byte[] signature = sig.sign(); sig.initVerify(dsaKeys.getPublic()); sig.update(MESSAGE.getBytes()); assertTrue("Sign/Verify does not pass", sig.verify(signature, 0, signature.length)); try { sig.verify(null, 0, signature.length); fail("IllegalArgumentException expected"); } catch (IllegalArgumentException e) { // expected } try { sig.verify(signature, -5, signature.length); fail("IllegalArgumentException expected"); } catch (IllegalArgumentException e) { // expected } try { sig.verify(signature, signature.length, 0); fail("SignatureException expected"); } catch (SignatureException e) { // expected } try { sig.verify(signature, 0, signature.length * 2); fail("IllegalArgumentException expected"); } catch (IllegalArgumentException e) { // expected } } class MyProvider extends Provider { private Set<Provider.Service> services = null; MyProvider() { super("MyProvider", 1.0, "Provider for testing"); put("MessageDigest.SHA-1", "SomeClassName"); put("MessageDigest.abc", "SomeClassName"); put("Alg.Alias.MessageDigest.SHA1", "SHA-1"); if (services != null) { services.clear(); } else { services = new HashSet<Service>(); } } MyProvider(String name, double version, String info) { super(name, version, info); if (services != null) { services.clear(); } else { services = new HashSet<Service>(); } } public void putService(Provider.Service s) { super.putService(s); services.add(s); } public void removeService(Provider.Service s) { super.removeService(s); services.remove(s); } public int getNumServices() { return services.size(); } } @SuppressWarnings("unused") private class MySignature extends Signature { protected MySignature(String algorithm) { super(algorithm); } @Override protected Object engineGetParameter(String param) throws InvalidParameterException { return null; } @Override protected void engineInitSign(PrivateKey privateKey) throws InvalidKeyException { } @Override protected void engineInitVerify(PublicKey publicKey) throws InvalidKeyException { } @Override protected void engineSetParameter(String param, Object value) throws InvalidParameterException { } @Override protected byte[] engineSign() throws SignatureException { return null; } @Override protected void engineUpdate(byte b) throws SignatureException { } @Override protected void engineUpdate(byte[] b, int off, int len) throws SignatureException { } @Override protected boolean engineVerify(byte[] sigBytes) throws SignatureException { return false; } @Override protected AlgorithmParameters engineGetParameters() { if (this.getAlgorithm().equals("test")) { return super.engineGetParameters(); } else { return null; } } } }