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 18package org.apache.harmony.security.tests.java.security; 19 20import java.io.IOException; 21import java.io.InputStream; 22import java.security.InvalidKeyException; 23import java.security.Key; 24import java.security.KeyStore.LoadStoreParameter; 25import java.security.KeyStore.Entry; 26import java.security.KeyStore.ProtectionParameter; 27import java.security.KeyStore; 28import java.security.KeyStoreException; 29import java.security.KeyStoreSpi; 30import java.security.NoSuchAlgorithmException; 31import java.security.NoSuchProviderException; 32import java.security.PublicKey; 33import java.security.SignatureException; 34import java.security.UnrecoverableEntryException; 35import java.security.UnrecoverableKeyException; 36import java.security.cert.Certificate; 37import java.security.cert.CertificateEncodingException; 38import java.security.cert.CertificateException; 39import java.util.Date; 40import javax.crypto.SecretKey; 41import junit.framework.TestCase; 42import org.apache.harmony.security.tests.support.MyKeyStoreSpi; 43import org.apache.harmony.security.tests.support.MyLoadStoreParams; 44 45public class KeyStoreSpiTest extends TestCase { 46 47 @SuppressWarnings("cast") 48 public void test_KeyStoreSpi() { 49 50 try { 51 MyKeyStoreSpi ksSpi = new MyKeyStoreSpi(); 52 assertNotNull(ksSpi); 53 assertTrue(ksSpi instanceof KeyStoreSpi); 54 } catch (Exception ex) { 55 fail("Unexpected exception"); 56 } 57 } 58 59 /* 60 * java.security.KeyStore.engineEntryInstanceOf(String, Class<? 61 * extends Entry>) 62 */ 63 public void test_engineEntryInstanceOf() throws Exception { 64 65 KeyStoreSpi ksSpi = new MyKeyStoreSpi(); 66 67 assertTrue(ksSpi.engineEntryInstanceOf( 68 "test_engineEntryInstanceOf_Alias1", 69 KeyStore.PrivateKeyEntry.class)); 70 71 assertFalse(ksSpi.engineEntryInstanceOf( 72 "test_engineEntryInstanceOf_Alias2", 73 KeyStore.SecretKeyEntry.class)); 74 75 assertFalse(ksSpi.engineEntryInstanceOf( 76 "test_engineEntryInstanceOf_Alias3", 77 KeyStore.TrustedCertificateEntry.class)); 78 79 try { 80 assertFalse(ksSpi.engineEntryInstanceOf(null, 81 KeyStore.TrustedCertificateEntry.class)); 82 } catch (NullPointerException expected) { 83 } 84 85 try { 86 assertFalse(ksSpi.engineEntryInstanceOf( 87 "test_engineEntryInstanceOf_Alias1", null)); 88 } catch (NullPointerException expected) { 89 } 90 91 92 } 93 94 public void testKeyStoreSpi01() throws IOException, 95 NoSuchAlgorithmException, CertificateException, 96 UnrecoverableEntryException, KeyStoreException { 97 final boolean[] keyEntryWasSet = new boolean[1]; 98 KeyStoreSpi ksSpi = new MyKeyStoreSpi() { 99 @Override public void engineSetKeyEntry(String alias, Key key, char[] password, 100 Certificate[] chain) throws KeyStoreException { keyEntryWasSet[0] = true; } 101 }; 102 103 BadKeyStoreEntry badEntry = new BadKeyStoreEntry(); 104 BadKeyStoreProtectionParameter badParameter = new BadKeyStoreProtectionParameter(); 105 106 KeyStore.SecretKeyEntry dummyEntry = new KeyStore.SecretKeyEntry(new SecretKey() { 107 @Override public String getAlgorithm() { return null; } 108 @Override public String getFormat() { return null; } 109 @Override public byte[] getEncoded() { return null; } 110 }); 111 112 try { 113 ksSpi.engineStore(null); 114 } catch (UnsupportedOperationException expected) { 115 } 116 assertNull("Not null entry", ksSpi.engineGetEntry("aaa", null)); 117 assertNull("Not null entry", ksSpi.engineGetEntry(null, badParameter)); 118 assertNull("Not null entry", ksSpi.engineGetEntry("aaa", badParameter)); 119 120 try { 121 ksSpi.engineSetEntry("", null, null); 122 fail("KeyStoreException or NullPointerException must be thrown"); 123 } catch (KeyStoreException expected) { 124 } catch (NullPointerException expected) { 125 } 126 127 try { 128 ksSpi.engineSetEntry("", new KeyStore.TrustedCertificateEntry( 129 new MyCertificate("type", new byte[0])), null); 130 fail("KeyStoreException must be thrown"); 131 } catch (KeyStoreException expected) { 132 } 133 134 try { 135 ksSpi.engineSetEntry("aaa", badEntry, null); 136 fail("KeyStoreException must be thrown"); 137 } catch (KeyStoreException expected) { 138 } 139 140 ksSpi.engineSetEntry("aaa", dummyEntry, null); 141 assertTrue(keyEntryWasSet[0]); 142 } 143 144 /** 145 * Test for <code>KeyStoreSpi()</code> constructor and abstract engine 146 * methods. Assertion: creates new KeyStoreSpi object. 147 */ 148 public void testKeyStoreSpi02() throws NoSuchAlgorithmException, 149 UnrecoverableKeyException, CertificateException { 150 KeyStoreSpi ksSpi = new MyKeyStoreSpi(); 151 assertNull("engineGetKey(..) must return null", ksSpi.engineGetKey("", 152 new char[0])); 153 assertNull("engineGetCertificateChain(..) must return null", ksSpi 154 .engineGetCertificateChain("")); 155 assertNull("engineGetCertificate(..) must return null", ksSpi 156 .engineGetCertificate("")); 157 assertEquals("engineGetCreationDate(..) must return Date(0)", new Date( 158 0), ksSpi.engineGetCreationDate("")); 159 try { 160 ksSpi.engineSetKeyEntry("", null, new char[0], new Certificate[0]); 161 fail("KeyStoreException must be thrown from engineSetKeyEntry(..)"); 162 } catch (KeyStoreException expected) { 163 } 164 try { 165 ksSpi.engineSetKeyEntry("", new byte[0], new Certificate[0]); 166 fail("KeyStoreException must be thrown from engineSetKeyEntry(..)"); 167 } catch (KeyStoreException expected) { 168 } 169 try { 170 ksSpi.engineSetCertificateEntry("", null); 171 fail("KeyStoreException must be thrown " 172 + "from engineSetCertificateEntry(..)"); 173 } catch (KeyStoreException expected) { 174 } 175 try { 176 ksSpi.engineDeleteEntry(""); 177 fail("KeyStoreException must be thrown from engineDeleteEntry(..)"); 178 } catch (KeyStoreException expected) { 179 } 180 assertNull("engineAliases() must return null", ksSpi.engineAliases()); 181 assertFalse("engineContainsAlias(..) must return false", ksSpi 182 .engineContainsAlias("")); 183 assertEquals("engineSize() must return 0", 0, ksSpi.engineSize()); 184 try { 185 ksSpi.engineStore(null, null); 186 fail("IOException must be thrown"); 187 } catch (IOException expected) { 188 } 189 } 190 191 /** 192 * java.security.KeyStoreSpi#engineLoad(KeyStore.LoadStoreParameter) 193 */ 194 public void test_engineLoadLjava_security_KeyStore_LoadStoreParameter() 195 throws Exception { 196 197 final String msg = "error"; 198 199 KeyStoreSpi ksSpi = new MyKeyStoreSpi() { 200 public void engineLoad(InputStream stream, char[] password) { 201 assertNull(stream); 202 assertNull(password); 203 throw new RuntimeException(msg); 204 } 205 }; 206 try { 207 ksSpi.engineLoad(null); 208 fail("Should throw exception"); 209 } catch (RuntimeException expected) { 210 assertSame(msg, expected.getMessage()); 211 } 212 213 // test: protection parameter is null 214 try { 215 ksSpi.engineLoad(new MyLoadStoreParams(null)); 216 fail("No expected UnsupportedOperationException"); 217 } catch (UnsupportedOperationException expected) { 218 } 219 220 // test: protection parameter is not instanceof 221 // PasswordProtection or CallbackHandlerProtection 222 try { 223 ksSpi.engineLoad(new MyLoadStoreParams(new BadKeyStoreProtectionParameter())); 224 fail("No expected UnsupportedOperationException"); 225 } catch (UnsupportedOperationException expected) { 226 } 227 } 228} 229 230// These are "Bad" because they are not expected inner subclasses of the KeyStore class. 231class BadKeyStoreEntry implements Entry {} 232class BadKeyStoreProtectionParameter implements ProtectionParameter {} 233 234@SuppressWarnings("unused") 235class MyCertificate extends Certificate { 236 237 // MyCertificate encoding 238 private final byte[] encoding; 239 240 public MyCertificate(String type, byte[] encoding) { 241 super(type); 242 // don't copy to allow null parameter in test 243 this.encoding = encoding; 244 } 245 246 public byte[] getEncoded() throws CertificateEncodingException { 247 // do copy to force NPE in test 248 return encoding.clone(); 249 } 250 251 public void verify(PublicKey key) throws CertificateException, 252 NoSuchAlgorithmException, InvalidKeyException, 253 NoSuchProviderException, SignatureException { 254 } 255 256 public void verify(PublicKey key, String sigProvider) 257 throws CertificateException, NoSuchAlgorithmException, 258 InvalidKeyException, NoSuchProviderException, SignatureException { 259 } 260 261 public String toString() { 262 return "[My test Certificate, type: " + getType() + "]"; 263 } 264 265 public PublicKey getPublicKey() { 266 return new PublicKey() { 267 public String getAlgorithm() { 268 return "DSA"; 269 } 270 271 public byte[] getEncoded() { 272 return new byte[] {(byte) 1, (byte) 2, (byte) 3}; 273 } 274 275 public String getFormat() { 276 return "TEST_FORMAT"; 277 } 278 }; 279 } 280} 281