blob: 75aada1427ded73becf0aadcc6b0e8f79990ff5e [file] [log] [blame]
/*
* Copyright (C) 2010 The Android Open Source Project
*
* Licensed 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 libcore.java.security;
import java.security.KeyFactory;
import java.security.KeyPair;
import java.security.KeyPairGenerator;
import java.security.Provider;
import java.security.PublicKey;
import java.security.Security;
import java.security.Signature;
import java.security.spec.X509EncodedKeySpec;
import java.util.HashMap;
import java.util.Map;
import java.util.Set;
import junit.framework.TestCase;
public class SignatureTest extends TestCase {
// 20 bytes for DSA
private final byte[] DATA = new byte[20];
public void test_getInstance() throws Exception {
Provider[] providers = Security.getProviders();
for (Provider provider : providers) {
Set<Provider.Service> services = provider.getServices();
for (Provider.Service service : services) {
String type = service.getType();
if (!type.equals("Signature")) {
continue;
}
String algorithm = service.getAlgorithm();
try {
KeyPair kp = keyPair(algorithm);
// Signature.getInstance(String)
Signature sig1 = Signature.getInstance(algorithm);
assertEquals(algorithm, sig1.getAlgorithm());
test_Signature(sig1, kp);
// Signature.getInstance(String, Provider)
Signature sig2 = Signature.getInstance(algorithm, provider);
assertEquals(algorithm, sig2.getAlgorithm());
assertEquals(provider, sig2.getProvider());
test_Signature(sig2, kp);
// Signature.getInstance(String, String)
Signature sig3 = Signature.getInstance(algorithm, provider.getName());
assertEquals(algorithm, sig3.getAlgorithm());
assertEquals(provider, sig3.getProvider());
test_Signature(sig3, kp);
} catch (Exception e) {
throw new Exception("Problem testing Signature." + algorithm, e);
}
}
}
}
private final Map<String, KeyPair> keypairAlgorithmToInstance
= new HashMap<String, KeyPair>();
private KeyPair keyPair(String sigAlgorithm) throws Exception {
if (sigAlgorithm.endsWith("Encryption")) {
sigAlgorithm = sigAlgorithm.substring(0, sigAlgorithm.length()-"Encryption".length());
}
String kpAlgorithm;
// note ECDSA must be before DSA
if (sigAlgorithm.endsWith("ECDSA")) {
kpAlgorithm = "EC";
} else if (sigAlgorithm.endsWith("DSA")) {
kpAlgorithm = "DSA";
} else if (sigAlgorithm.endsWith("RSA")) {
kpAlgorithm = "RSA";
} else {
throw new Exception("Unknown KeyPair algorithm for Signature algorithm "
+ sigAlgorithm);
}
KeyPair kp = keypairAlgorithmToInstance.get(kpAlgorithm);
if (kp == null) {
kp = KeyPairGenerator.getInstance(kpAlgorithm).generateKeyPair();
keypairAlgorithmToInstance.put(sigAlgorithm, kp);
}
return kp;
}
private void test_Signature(Signature sig, KeyPair keyPair) throws Exception {
sig.initSign(keyPair.getPrivate());
sig.update(DATA);
byte[] signature = sig.sign();
assertNotNull(signature);
assertTrue(signature.length > 0);
sig.initVerify(keyPair.getPublic());
sig.update(DATA);
assertTrue(sig.verify(signature));
}
private static final byte[] PK_BYTES = hexToBytes(
"30819f300d06092a864886f70d010101050003818d0030818902818100cd769d178f61475fce3001"
+ "2604218320c77a427121d3b41dd76756c8fc0c428cd15cb754adc85466f47547b1c85623d9c17fc6"
+ "4f202fca21099caf99460c824ad657caa8c2db34996838d32623c4f23c8b6a4e6698603901262619"
+ "4840e0896b1a6ec4f6652484aad04569bb6a885b822a10d700224359c632dc7324520cbb3d020301"
+ "0001");
private static final byte[] CONTENT = hexToBytes(
"f2fa9d73656e00fa01edc12e73656e2e7670632e6432004867268c46dd95030b93ce7260423e5c00"
+ "fabd4d656d6265727300fa018dc12e73656e2e7670632e643100d7c258dc00fabd44657669636573"
+ "00faa54b65797300fa02b5c12e4d2e4b009471968cc68835f8a68dde10f53d19693d480de767e5fb"
+ "976f3562324006372300fabdfd04e1f51ef3aa00fa8d00000001a203e202859471968cc68835f8a6"
+ "8dde10f53d19693d480de767e5fb976f356232400637230002bab504e1f51ef5810002c29d28463f"
+ "0003da8d000001e201eaf2fa9d73656e00fa01edc12e73656e2e7670632e6432004867268c46dd95"
+ "030b93ce7260423e5c00fabd4d656d6265727300fa018dc12e73656e2e7670632e643100d7c258dc"
+ "00fabd4465766963657300faa54b65797300fa02b5c12e4d2e4b009471968cc68835f8a68dde10f5"
+ "3d19693d480de767e5fb976f3562324006372300fabdfd04e1f51ef3aa000003e202859471968cc6"
+ "8835f8a68dde10f53d19693d480de767e5fb976f3562324006372300000000019a0a9530819f300d"
+ "06092a864886f70d010101050003818d0030818902818100cd769d178f61475fce30012604218320"
+ "c77a427121d3b41dd76756c8fc0c428cd15cb754adc85466f47547b1c85623d9c17fc64f202fca21"
+ "099caf99460c824ad657caa8c2db34996838d32623c4f23c8b6a4e66986039012626194840e0896b"
+ "1a6ec4f6652484aad04569bb6a885b822a10d700224359c632dc7324520cbb3d020301000100");
private static final byte[] SIGNATURE = hexToBytes(
"b4016456148cd2e9f580470aad63d19c1fee52b38c9dcb5b4d61a7ca369a7277497775d106d86394"
+ "a69229184333b5a3e6261d5bcebdb02530ca9909f4d790199eae7c140f7db39dee2232191bdf0bfb"
+ "34fdadc44326b9b3f3fa828652bab07f0362ac141c8c3784ebdec44e0b156a5e7bccdc81a56fe954"
+ "56ac8c0e4ae12d97");
private static byte[] hexToBytes(String s) {
int len = s.length();
byte[] data = new byte[len / 2];
for (int i = 0; i < len; i += 2) {
data[i / 2] = (byte) ((Character.digit(s.charAt(i), 16) << 4)
+ Character.digit(s.charAt(i+1), 16));
}
return data;
}
// http://code.google.com/p/android/issues/detail?id=18566
// http://b/5038554
public void test18566() throws Exception {
X509EncodedKeySpec keySpec = new X509EncodedKeySpec(PK_BYTES);
KeyFactory keyFactory = KeyFactory.getInstance("RSA");
PublicKey pk = keyFactory.generatePublic(keySpec);
Signature sig = Signature.getInstance("SHA256withRSA");
sig.initVerify(pk);
sig.update(CONTENT);
assertTrue(sig.verify(SIGNATURE));
}
}