jdk/test/java/security/KeyStore/EntryMethods.java
author duke
Sat, 01 Dec 2007 00:00:00 +0000
changeset 2 90ce3da70b43
child 5506 202f599c92aa
permissions -rw-r--r--
Initial load

/*
 * Copyright 2003-2004 Sun Microsystems, Inc.  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 Sun Microsystems, Inc., 4150 Network Circle, Santa Clara,
 * CA 95054 USA or visit www.sun.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();
        }
    }
}