1 /* 2 * Copyright (C) 2009 The Android Open Source Project 3 * 4 * Licensed under the Apache License, Version 2.0 (the "License"); 5 * you may not use this file except in compliance with the License. 6 * You may obtain a copy of the License at 7 * 8 * http://www.apache.org/licenses/LICENSE-2.0 9 * 10 * Unless required by applicable law or agreed to in writing, software 11 * distributed under the License is distributed on an "AS IS" BASIS, 12 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 * See the License for the specific language governing permissions and 14 * limitations under the License. 15 */ 16 package tests.targets.security; 17 18 import java.io.ByteArrayInputStream; 19 import java.io.ByteArrayOutputStream; 20 import java.io.IOException; 21 import java.io.InputStream; 22 import java.security.KeyPair; 23 import java.security.KeyPairGenerator; 24 import java.security.KeyStore; 25 import java.security.KeyStore.Entry; 26 import java.security.KeyStore.PasswordProtection; 27 import java.security.KeyStore.PrivateKeyEntry; 28 import java.security.KeyStore.ProtectionParameter; 29 import java.security.KeyStoreException; 30 import java.security.NoSuchAlgorithmException; 31 import java.security.PrivateKey; 32 import java.security.UnrecoverableEntryException; 33 import java.security.cert.Certificate; 34 import java.security.cert.CertificateException; 35 import java.security.cert.CertificateFactory; 36 import junit.framework.TestCase; 37 38 public abstract class KeyStoreTest extends TestCase { 39 40 private final String algorithmName; 41 private final byte[] keyStoreData; 42 private final String keyStorePassword; 43 44 public KeyStoreTest(String algorithmName, byte[] keyStoreData, 45 String keyStorePassword) { 46 this.algorithmName = algorithmName; 47 this.keyStoreData = keyStoreData; 48 this.keyStorePassword = keyStorePassword; 49 } 50 51 public void testKeyStoreLoad() { 52 KeyStore keyStore = null; 53 try { 54 keyStore = KeyStore.getInstance(algorithmName); 55 } catch (KeyStoreException e) { 56 fail(e.getMessage()); 57 } 58 59 try { 60 keyStore.load(new ByteArrayInputStream(keyStoreData), 61 keyStorePassword.toCharArray()); 62 } catch (NoSuchAlgorithmException e) { 63 fail(e.getMessage()); 64 } catch (CertificateException e) { 65 fail(e.getMessage()); 66 } catch (IOException e) { 67 fail(e.getMessage()); 68 } 69 70 try { 71 assertTrue("keystore is empty", keyStore.aliases() 72 .hasMoreElements()); 73 } catch (KeyStoreException e) { 74 fail(e.getMessage()); 75 } 76 } 77 78 public void testKeyStoreCreate() { 79 KeyStore keyStore = null; 80 try { 81 keyStore = KeyStore.getInstance(algorithmName); 82 } catch (KeyStoreException e) { 83 fail(e.getMessage()); 84 } 85 86 try { 87 keyStore.load(null, "the secret password".toCharArray()); 88 } catch (NoSuchAlgorithmException e) { 89 fail(e.getMessage()); 90 } catch (CertificateException e) { 91 fail(e.getMessage()); 92 } catch (IOException e) { 93 fail(e.getMessage()); 94 } 95 96 CertificateFactory certificateFactory = null; 97 try { 98 certificateFactory = CertificateFactory.getInstance("X.509"); 99 } catch (CertificateException e) { 100 fail(e.getMessage()); 101 } 102 103 Certificate certificate = null; 104 try { 105 certificate = certificateFactory 106 .generateCertificate(new ByteArrayInputStream( 107 encodedCertificate.getBytes())); 108 } catch (CertificateException e) { 109 fail(e.getMessage()); 110 } 111 112 KeyPairGenerator generator = null; 113 try { 114 generator = KeyPairGenerator.getInstance(certificate.getPublicKey() 115 .getAlgorithm()); 116 } catch (NoSuchAlgorithmException e) { 117 fail(e.getMessage()); 118 } 119 120 KeyPair keyPair = generator.generateKeyPair(); 121 122 PrivateKeyEntry privateKeyEntry = new PrivateKeyEntry(keyPair 123 .getPrivate(), new Certificate[] {certificate}); 124 125 try { 126 keyStore.setEntry("aPrivateKey", privateKeyEntry, 127 new PasswordProtection("the key password".toCharArray())); 128 } catch (KeyStoreException e) { 129 fail(e.getMessage()); 130 } 131 132 try { 133 assertTrue(keyStore.containsAlias("aPrivateKey")); 134 } catch (KeyStoreException e) { 135 fail(e.getMessage()); 136 } 137 138 try { 139 PrivateKeyEntry entry = (PrivateKeyEntry) keyStore.getEntry( 140 "aPrivateKey", new PasswordProtection("the key password" 141 .toCharArray())); 142 PrivateKey privateKey = entry.getPrivateKey(); 143 assertEquals(keyPair.getPrivate(), privateKey); 144 } catch (NoSuchAlgorithmException e) { 145 fail(e.getMessage()); 146 } catch (UnrecoverableEntryException e) { 147 fail(e.getMessage()); 148 } catch (KeyStoreException e) { 149 fail(e.getMessage()); 150 } 151 152 try { 153 ByteArrayOutputStream stream = new ByteArrayOutputStream(); 154 keyStore.store(stream, "the keystore password".toCharArray()); 155 assertTrue("keystore not written", stream.size() > 0); 156 } catch (KeyStoreException e) { 157 fail(e.getMessage()); 158 } catch (NoSuchAlgorithmException e) { 159 fail(e.getMessage()); 160 } catch (CertificateException e) { 161 fail(e.getMessage()); 162 } catch (IOException e) { 163 fail(e.getMessage()); 164 } 165 } 166 167 private String encodedCertificate = "-----BEGIN CERTIFICATE-----\n" 168 + "MIID0jCCAzugAwIBAgIBAjANBgkqhkiG9w0BAQQFADCBmjELMAkGA1UEBhMCVUsx\n" 169 + "EjAQBgNVBAgTCUhhbXBzaGlyZTETMBEGA1UEBxMKV2luY2hlc3RlcjETMBEGA1UE\n" 170 + "ChMKSUJNIFVLIEx0ZDEMMAoGA1UECxMDSlRDMRYwFAYDVQQDEw1QYXVsIEggQWJi\n" 171 + "b3R0MScwJQYJKoZIhvcNAQkBFhhQYXVsX0hfQWJib3R0QHVrLmlibS5jb20wHhcN\n" 172 + "MDQwNjIyMjA1MDU1WhcNMDUwNjIyMjA1MDU1WjCBmDELMAkGA1UEBhMCVUsxEjAQ\n" 173 + "BgNVBAgTCUhhbXBzaGlyZTETMBEGA1UEBxMKV2luY2hlc3RlcjETMBEGA1UEChMK\n" 174 + "SUJNIFVrIEx0ZDEMMAoGA1UECxMDSkVUMRQwEgYDVQQDEwtQYXVsIEFiYm90dDEn\n" 175 + "MCUGCSqGSIb3DQEJARYYUGF1bF9IX0FiYm90dEB1ay5pYm0uY29tMIGfMA0GCSqG\n" 176 + "SIb3DQEBAQUAA4GNADCBiQKBgQDitZBQ5d18ecNJpcnuKTraHYtqsAugoc95/L5Q\n" 177 + "28s3t1QAu2505qQR1MZaAkY7tDNyl1vPnZoym+Y06UswTrZoVYo/gPNeyWPMTsLA\n" 178 + "wzQvk5/6yhtE9ciH7B0SqYw6uSiDTbUY/zQ6qed+TsQhjlbn3PUHRjnI2P8A04cg\n" 179 + "LgYYGQIDAQABo4IBJjCCASIwCQYDVR0TBAIwADAsBglghkgBhvhCAQ0EHxYdT3Bl\n" 180 + "blNTTCBHZW5lcmF0ZWQgQ2VydGlmaWNhdGUwHQYDVR0OBBYEFPplRPs65hUfxUBs\n" 181 + "6/Taq7nN8i1UMIHHBgNVHSMEgb8wgbyAFJOMtPAwlXdZLqE7DKU6xpL6FjFtoYGg\n" 182 + "pIGdMIGaMQswCQYDVQQGEwJVSzESMBAGA1UECBMJSGFtcHNoaXJlMRMwEQYDVQQH\n" 183 + "EwpXaW5jaGVzdGVyMRMwEQYDVQQKEwpJQk0gVUsgTHRkMQwwCgYDVQQLEwNKVEMx\n" 184 + "FjAUBgNVBAMTDVBhdWwgSCBBYmJvdHQxJzAlBgkqhkiG9w0BCQEWGFBhdWxfSF9B\n" 185 + "YmJvdHRAdWsuaWJtLmNvbYIBADANBgkqhkiG9w0BAQQFAAOBgQAnQ22Jw2HUrz7c\n" 186 + "VaOap31mTikuQ/CQxpwPYiSyTJ4s99eEzn+2yAk9tIDIJpqoay/fj+OLgPUQKIAo\n" 187 + "XpRVvmHlGE7UqMKebZtSZJQzs6VoeeKFhgHmqg8eVC2AsTc4ZswJmg4wCui5AH3a\n" 188 + "oqG7PIM3LxZqXYQlZiPSZ6kCpDOWVg==\n" 189 + "-----END CERTIFICATE-----\n"; 190 } 191