/*
* Copyright (c) 2003, 2004, Oracle and/or its affiliates. All rights reserved.
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
*
* This code is free software; you can redistribute it and/or modify it
* under the terms of the GNU General Public License version 2 only, as
* published by the Free Software Foundation.
*
* This code is distributed in the hope that it will be useful, but WITHOUT
* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
* FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
* version 2 for more details (a copy is included in the LICENSE file that
* accompanied this code).
*
* You should have received a copy of the GNU General Public License version
* 2 along with this work; if not, write to the Free Software Foundation,
* Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
*
* Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
* or visit www.oracle.com if you need additional information or have any
* questions.
*/
/*
* @test 1.5, 03/06/24
* @bug 4850376
* @summary Provide generic storage KeyStore storage facilities
*/
import java.security.*;
import java.security.cert.*;
import java.util.*;
import java.io.*;
import sun.security.provider.*;
public class EntryMethods
extends Provider
implements KeyStore.Entry
{
private static FileInputStream pre15fis;
private static char[] password = {'f', 'o', 'o', 'b', 'a', 'r'};
private static char[] badPwd = {'b', 'a', 'd', 'p', 'w', 'd'};
public static class FooProtect implements KeyStore.ProtectionParameter { }
public static class FooParameter implements KeyStore.LoadStoreParameter {
public KeyStore.ProtectionParameter getProtectionParameter() {
return null;
}
}
public static class FooEntry implements KeyStore.Entry { }
public EntryMethods() throws Exception {
super("EntryMethods", 0.0, "EntryMethods");
pre15fis = new FileInputStream
(System.getProperty("test.src") + "/EntryMethods.pre15.keystore");
AccessController.doPrivileged(new PrivilegedAction() {
public Object run() {
put("KeyStore.Pre15KeyStore", "EntryMethods$Pre15");
put("KeyStore.Post15KeyStore", "EntryMethods$Post15");
put("KeyStore.UnrecoverableKeyStore",
"EntryMethods$UnrecoverableKS");
return null;
}
});
}
public static void main(String[] args) throws Exception {
EntryMethods entry = new EntryMethods();
// test pre-JDK1.5 KeyStore throws UnsupportedOperationExceptions
// for new methods
KeyStore pre15KS = KeyStore.getInstance("Pre15KeyStore", entry);
testPre15(pre15KS);
// test post-JDK1.5 KeyStore does right thing with new methods
KeyStore post15KS = KeyStore.getInstance("Post15KeyStore", entry);
testPost15(post15KS);
// test post-JDK1.5 KeyStore can throw new UnrecoverableEntryException
KeyStore uKS = KeyStore.getInstance("UnrecoverableKeyStore", entry);
testUnrecoverable(uKS);
}
private static void testPre15(KeyStore ks) throws Exception {
int tNum = 1;
KeyStore.Entry e = null;
// TEST load null param
ks.load((KeyStore.LoadStoreParameter)null);
System.out.println("[Pre1.5] test " + tNum++ + " passed");
// TEST load random param
try {
ks.load(new FooParameter());
throw new SecurityException("[Pre1.5] test " + tNum + " failed");
} catch (UnsupportedOperationException uoe) {
System.out.println("[Pre1.5] test " + tNum++ + " passed");
}
// TEST store random param
ks.load(pre15fis, password);
// setup for later user
KeyStore.Entry pkeNew = ks.getEntry("privkey",
new KeyStore.PasswordProtection(password));
KeyStore.Entry tceNew = ks.getEntry("trustedcert", null);
try {
ks.store(new FooParameter());
throw new SecurityException("[Pre1.5] test " + tNum + " failed");
} catch (UnsupportedOperationException uoe) {
// good
System.out.println("[Pre1.5] test " + tNum++ + " passed");
}
// TEST store null param
try {
ks.store(null);
throw new SecurityException("[Pre1.5] test " + tNum + " failed");
} catch (UnsupportedOperationException uoe) {
// good
System.out.println("[Pre1.5] test " + tNum++ + " passed");
}
// TEST getEntry with alias/protParam - use invalid alias
e = ks.getEntry("notPresent",
new KeyStore.PasswordProtection(password));
if (e == null) {
System.out.println("[Pre1.5] test " + tNum++ + " passed");
} else {
throw new SecurityException("[Pre1.5] test " + tNum + " failed - " +
"expected null entry returned");
}
// TEST getEntry with alias/null protParam - get private key
try {
e = ks.getEntry("privkey", null);
throw new SecurityException("[Pre1.5] test " + tNum + " failed - " +
"expected UnrecoverableEntryException");
} catch (UnrecoverableEntryException uee) {
System.out.println("[Pre1.5] test " + tNum++ + " passed");
}
// TEST getEntry with alias/bad password - get private key
try {
e = ks.getEntry("privkey",
new KeyStore.PasswordProtection(badPwd));
throw new SecurityException("[Pre1.5] test " + tNum + " failed - " +
"expected UnrecoverableEntryException");
} catch (UnrecoverableEntryException uee) {
System.out.println("[Pre1.5] test " + tNum++ + " passed");
}
// TEST getEntry with alias/unknown protection - get private key
try {
e = ks.getEntry("privkey", new FooProtect());
throw new SecurityException("[Pre1.5] test " + tNum + " failed - " +
"expected UnsupportedOperationException");
} catch (UnsupportedOperationException uoe) {
System.out.println("[Pre1.5] test " + tNum++ + " passed");
}
// TEST getEntry with alias/protParam - get private key
e = ks.getEntry("privkey", new KeyStore.PasswordProtection(password));
if (e instanceof KeyStore.PrivateKeyEntry) {
System.out.println("[Pre1.5] test " + tNum++ + " passed");
} else {
throw new SecurityException("[Pre1.5] test " + tNum + " failed - " +
"expected PrivateKeyEntry");
}
// TEST getEntry with alias/null protParam - get trusted cert
e = ks.getEntry("trustedcert", null);
if (e instanceof KeyStore.TrustedCertificateEntry) {
System.out.println("[Pre1.5] test " + tNum++ + " passed");
} else {
throw new SecurityException("[Pre1.5] test " + tNum + " failed");
}
// TEST getEntry with alias/non-null protParam - get trusted cert
try {
e = ks.getEntry("trustedcert",
new KeyStore.PasswordProtection(password));
throw new SecurityException("[Pre1.5] test " + tNum + " failed");
} catch (UnsupportedOperationException uoe) {
System.out.println("[Pre1.5] test " + tNum++ + " passed");
}
// TEST setEntry with alias/entry/protParam - use invalid alias
try {
ks.setEntry("foo", new FooEntry(),
new KeyStore.PasswordProtection(password));
throw new SecurityException("[Pre1.5] test " + tNum + " failed - " +
"expected KeyStoreException");
} catch (KeyStoreException kse) {
// good
System.out.println("[Pre1.5] test " + tNum++ + " passed");
}
// TEST setEntry with alias/entry/null protParam - set private key
try {
ks.setEntry("newPrivKey", pkeNew, null);
throw new SecurityException("[Pre1.5] test " + tNum + " failed - " +
"expected KeyStoreException");
} catch (KeyStoreException kse) {
System.out.println("[Pre1.5] test " + tNum++ + " passed");
}
// TEST setEntry with alias/entry/random protParam - set private key
try {
ks.setEntry("newPrivKey", pkeNew, new FooProtect());
throw new SecurityException("[Pre1.5] test " + tNum + " failed - " +
"expected KeyStoreException");
} catch (KeyStoreException kse) {
System.out.println("[Pre1.5] test " + tNum++ + " passed");
}
// TEST setEntry with alias/entry/protParam - set private key
ks.setEntry("newPrivKey", pkeNew,
new KeyStore.PasswordProtection(password));
e = ks.getEntry("newPrivKey",
new KeyStore.PasswordProtection(password));
if (e instanceof KeyStore.PrivateKeyEntry) {
System.out.println("[Pre1.5] test " + tNum++ + " passed");
} else {
throw new SecurityException("[Pre1.5] test " + tNum + " failed - " +
"expected PrivateKeyEntry");
}
// TEST setEntry with alias/entry/non null protParam - set trusted cert
try {
ks.setEntry("newTrustedcert", tceNew,
new KeyStore.PasswordProtection(password));
throw new SecurityException("[Pre1.5] test " + tNum + " failed - " +
"expected KeyStoreException");
} catch (KeyStoreException kse) {
// good
System.out.println("[Pre1.5] test " + tNum++ + " passed");
}
// TEST setEntry with alias/entry/null protParam - set trusted cert
ks.setEntry("newTrustedcert", tceNew, null);
e = ks.getEntry("newTrustedcert", null);
if (e instanceof KeyStore.TrustedCertificateEntry) {
System.out.println("[Pre1.5] test " + tNum++ + " passed");
} else {
throw new SecurityException("[Pre1.5] test " + tNum + " failed - " +
"expected TrustedCertificateEntry");
}
// TEST entryInstanceOf - invalid alias
if (ks.entryInstanceOf("foo", EntryMethods.class) == false) {
System.out.println("[Pre1.5] test " + tNum++ + " passed");
} else {
throw new SecurityException("[Pre1.5] test " + tNum + " failed");
}
// TEST entryInstanceOf - false case
if (ks.entryInstanceOf("privkey", EntryMethods.class) == false) {
System.out.println("[Pre1.5] test " + tNum++ + " passed");
} else {
throw new SecurityException("[Pre1.5] test " + tNum + " failed");
}
// TEST entryInstanceOf - true case, trustedcert entry
if (ks.entryInstanceOf("trustedcert",
KeyStore.TrustedCertificateEntry.class)) {
System.out.println("[Pre1.5] test " + tNum++ + " passed");
} else {
throw new SecurityException("[Pre1.5] test " + tNum + " failed");
}
// TEST entryInstanceOf - true case, private key entry
if (ks.entryInstanceOf("privkey",
KeyStore.PrivateKeyEntry.class)) {
System.out.println("[Pre1.5] test " + tNum++ + " passed");
} else {
throw new SecurityException("[Pre1.5] test " + tNum + " failed");
}
}
private static void testPost15(KeyStore ks) throws Exception {
KeyStore.Entry e = null;
ks.load(new EntryMethods.FooParameter());
ks.store(new EntryMethods.FooParameter());
e = ks.getEntry("foo", new KeyStore.PasswordProtection(password));
if (!(e instanceof EntryMethods.FooEntry)) {
throw new SecurityException
("testPost15 getEntry(String, ProtParm) " +
"expected EntryMethods.FooEntry returned");
}
ks.setEntry("foo", new EntryMethods.FooEntry(),
new KeyStore.PasswordProtection(password));
if (!ks.entryInstanceOf("foo", KeyStore.PrivateKeyEntry.class)) {
throw new SecurityException
("testPost15 entryInstanceOf(String, Class) " +
"expected true returned");
}
System.out.println("[Post1.5] tests all passed");
}
private static void testUnrecoverable(KeyStore ks) throws Exception {
ks.load(new EntryMethods.FooParameter());
try {
ks.getEntry("foo", new KeyStore.PasswordProtection(password));
throw new SecurityException
("UnrecoverableEntryException not thrown for " +
"getEntry(String, ProtectionParam)");
} catch (UnrecoverableEntryException uee) {
// good
System.out.println("[UnrecoverableEntry] test passed");
}
}
public static class Pre15 extends KeyStoreSpi {
private static KeyStoreSpi jks = getJKS();
// javac does not allow direct access to class (javac bug?)
// use reflection instead
private static KeyStoreSpi getJKS() {
try {
Class clazz = Class.forName("sun.security.provider.JavaKeyStore$JKS");
return (KeyStoreSpi)clazz.newInstance();
} catch (Exception e) {
e.printStackTrace();
throw new RuntimeException(e);
}
}
public Key engineGetKey(String alias, char[] password)
throws NoSuchAlgorithmException, UnrecoverableKeyException {
return jks.engineGetKey(alias, password);
}
public java.security.cert.Certificate[] engineGetCertificateChain
(String alias) {
return jks.engineGetCertificateChain(alias);
}
public java.security.cert.Certificate engineGetCertificate
(String alias) {
return jks.engineGetCertificate(alias);
}
public Date engineGetCreationDate(String alias) {
return jks.engineGetCreationDate(alias);
}
public void engineSetKeyEntry(String alias, Key key,
char[] password,
java.security.cert.Certificate[] chain)
throws KeyStoreException {
jks.engineSetKeyEntry(alias, key, password, chain);
}
public void engineSetKeyEntry(String alias, byte[] key,
java.security.cert.Certificate[] chain)
throws KeyStoreException {
jks.engineSetKeyEntry(alias, key, chain);
}
public void engineSetCertificateEntry(String alias,
java.security.cert.Certificate cert)
throws KeyStoreException {
jks.engineSetCertificateEntry(alias, cert);
}
public void engineDeleteEntry(String alias)
throws KeyStoreException {
jks.engineDeleteEntry(alias);
}
public Enumeration engineAliases() {
return jks.engineAliases();
}
public boolean engineContainsAlias(String alias) {
return jks.engineContainsAlias(alias);
}
public int engineSize() {
return jks.engineSize();
}
public boolean engineIsKeyEntry(String alias) {
return jks.engineIsKeyEntry(alias);
}
public boolean engineIsCertificateEntry(String alias) {
return jks.engineIsCertificateEntry(alias);
}
public String engineGetCertificateAlias
(java.security.cert.Certificate cert) {
return jks.engineGetCertificateAlias(cert);
}
public void engineStore(OutputStream stream, char[] password)
throws IOException, NoSuchAlgorithmException, CertificateException {
jks.engineStore(stream, password);
}
public void engineLoad(InputStream stream, char[] password)
throws IOException, NoSuchAlgorithmException, CertificateException {
jks.engineLoad(stream, password);
}
}
public static class Post15 extends Pre15 {
public void engineStore(KeyStore.LoadStoreParameter parameter)
throws IOException, NoSuchAlgorithmException, CertificateException {
if (!(parameter instanceof EntryMethods.FooParameter)) {
throw new IOException("Post15 engineStore method expected " +
"FooParameter");
}
}
public void engineLoad(KeyStore.LoadStoreParameter parameter)
throws IOException, NoSuchAlgorithmException, CertificateException {
if (!(parameter instanceof EntryMethods.FooParameter)) {
throw new IOException("Post15 engineLoadFrom method expected " +
"FooParameter");
}
}
public KeyStore.Entry engineGetEntry(String alias,
KeyStore.ProtectionParameter protectionParam)
throws UnrecoverableEntryException {
if (!alias.equals("foo")) {
throw new SecurityException
("Post15 engineGetEntry(String, ProtectionParam) " +
"expected [foo] alias");
}
KeyStore.PasswordProtection pwdParam =
(KeyStore.PasswordProtection)protectionParam;
if (pwdParam.getPassword().length != 6) {
throw new SecurityException
("Post15 engineGetEntry(String, ProtectionParam) " +
"expected [foobar] password");
}
return new EntryMethods.FooEntry();
}
public void engineSetEntry(String alias, KeyStore.Entry entry,
KeyStore.ProtectionParameter protectionParam) {
if (!alias.equals("foo") ||
!(entry instanceof EntryMethods.FooEntry)) {
throw new SecurityException
("Post15 engineSetEntry(String, entry, ProtParm) " +
"expected [foo] alias and EntryMethods.FooEntry");
}
KeyStore.PasswordProtection pwdParam =
(KeyStore.PasswordProtection)protectionParam;
if (pwdParam.getPassword().length != 6) {
throw new SecurityException
("Post15 engineSetEntry(String, entry, ProtParm) " +
"expected [foobar] password");
}
}
public boolean engineEntryInstanceOf(String alias,
Class<? extends KeyStore.Entry> entryClass)
{
if (!alias.equals("foo") ||
entryClass != KeyStore.PrivateKeyEntry.class) {
throw new SecurityException
("Post15 engineEntryInstanceOf(String, Class) " +
"expected [foo] alias " +
"and [KeyStore.PrivateKeyEntry] class");
}
return true;
}
}
public static class UnrecoverableKS extends Post15 {
public KeyStore.Entry engineGetEntry(String alias,
KeyStore.ProtectionParameter protectionParam)
throws UnrecoverableEntryException {
throw new UnrecoverableEntryException();
}
}
}