/*
 * Copyright (c) 2003, 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
 * @bug 4919147
 * @summary Support for token-based KeyStores
 */

import java.io.File;
import java.io.IOException;
import java.util.Map;
import java.util.HashMap;

import javax.security.auth.*;
import javax.security.auth.login.*;
import javax.security.auth.callback.*;
import com.sun.security.auth.module.KeyStoreLoginModule;

public class OptionTest {

    private static final String TEST = "OptionTest";
    private static int testnum = 1;

    private static final String O_URL = "keyStoreURL";
    private static final String O_ALIAS = "keyStoreAlias";
    private static final String O_TYPE = "keyStoreType";
    private static final String O_SPASS_URL = "keyStorePasswordURL";
    private static final String O_KPASS_URL = "privateKeyPasswordURL";
    private static final String O_PPATH = "protected";
    private static final String NONE = "NONE";

    private static String URL;
    private static String SPASS_URL;
    private static String KPASS_URL;

    private static final String P11KEYSTORE = "PKCS11";
    private static final String ALIAS = "alias";
    private static final char[] STORE_PASS = new char[]
        { 's', 't', 'o', 'r', 'e', 'P', 'a', 's', 's' };  // sync with file
    private static final char[] KEY_PASS =
        { 'k', 'e', 'y', 'P', 'a', 's', 's' };            // sync with file

    public static void main(String[] args) throws Exception {
        init();
        testInvalidOptions();
        testNullCallbackHandler();
        testWithCallbackHandler();
    }

    private static void init() throws Exception {
        File f = new File(System.getProperty("test.src", ".") +
                        File.separatorChar +
                        TEST +
                        ".keystore");
        URL = f.toURI().toURL().toString();

        f = new File(System.getProperty("test.src", ".") +
                        File.separatorChar +
                        TEST +
                        ".storePass");
        SPASS_URL = f.toURI().toURL().toString();

        f = new File(System.getProperty("test.src", ".") +
                        File.separatorChar +
                        TEST +
                        ".keyPass");
        KPASS_URL = f.toURI().toURL().toString();
    }

    private static void testInvalidOptions() throws Exception {

        // if keyStoreType is PKCS11, keyStoreURL must be NONE

        KeyStoreLoginModule m = new KeyStoreLoginModule();
        Subject s = new Subject();
        Map options = new HashMap();
        options.put(O_TYPE, P11KEYSTORE);
        m.initialize(s, null, null, options);
        try {
            m.login();
            throw new SecurityException("expected exception");
        } catch (LoginException le) {
            // good
            //le.printStackTrace();
            System.out.println("test " + testnum++ + " passed");
        }

        // if keyStoreType is PKCS11, keyStoreURL is NONE,
        // then privateKeyPasswordURL must not be specified

        options = new HashMap();
        options.put(O_TYPE, P11KEYSTORE);
        options.put(O_URL, NONE);
        options.put(O_KPASS_URL, KPASS_URL);
        m.initialize(s, null, null, options);
        try {
            m.login();
            throw new SecurityException("expected exception");
        } catch (LoginException le) {
            // good
            //le.printStackTrace();
            System.out.println("test " + testnum++ + " passed");
        }

        // if protected is true, keyStorePasswordURL must not be specified

        options = new HashMap();
        options.put(O_PPATH, "true");
        options.put(O_SPASS_URL, SPASS_URL);
        m.initialize(s, null, null, options);
        try {
            m.login();
            throw new SecurityException("expected exception");
        } catch (LoginException le) {
            // good
            //le.printStackTrace();
            System.out.println("test " + testnum++ + " passed");
        }

        // if protected is true, privateKeyPasswordURL must not be specified

        options = new HashMap();
        options.put(O_PPATH, "true");
        options.put(O_KPASS_URL, KPASS_URL);
        m.initialize(s, null, null, options);
        try {
            m.login();
            throw new SecurityException("expected exception");
        } catch (LoginException le) {
            // good
            //le.printStackTrace();
            System.out.println("test " + testnum++ + " passed");
        }
    }

    private static void testNullCallbackHandler() throws Exception {

        // no options (missing alias)

        KeyStoreLoginModule m = new KeyStoreLoginModule();
        Subject s = new Subject();
        Map options = new HashMap();
        m.initialize(s, null, null, options);
        try {
            m.login();
            throw new SecurityException("expected exception");
        } catch (LoginException le) {
            // good
            //le.printStackTrace();
            System.out.println("test " + testnum++ + " passed");
        }

        // missing passwords

        options.put(O_ALIAS, ALIAS);
        m.initialize(s, null, null, options);
        try {
            m.login();
            throw new SecurityException("expected exception");
        } catch (LoginException le) {
            // good
            //le.printStackTrace();
            System.out.println("test " + testnum++ + " passed");
        }

        // no private key password
        // (private key password is different from store password)

        options.put(O_SPASS_URL, SPASS_URL);
        m.initialize(s, null, null, options);
        try {
            m.login();
            throw new SecurityException("expected exception");
        } catch (LoginException le) {
            // good
            //le.printStackTrace();
            System.out.println("test " + testnum++ + " passed");
        }

        // all necessary options
        // (private key password is different from store password)

        options.put(O_URL, URL);
        options.put(O_KPASS_URL, KPASS_URL);
        m.initialize(s, null, null, options);
        m.login();
        System.out.println("test " + testnum++ + " passed");
    }

    private static void testWithCallbackHandler() throws Exception {

        KeyStoreLoginModule m = new KeyStoreLoginModule();
        Subject s = new Subject();
        Map options = new HashMap();
        options.put(O_URL, URL);

        CallbackHandler goodHandler = new MyCallbackHandler(true);
        m.initialize(s, goodHandler, null, options);
        m.login();
        System.out.println("test " + testnum++ + " passed");

        CallbackHandler badHandler = new MyCallbackHandler(false);
        m.initialize(s, badHandler, null, options);
        try {
            m.login();
            throw new SecurityException("expected LoginException");
        } catch (LoginException le) {
            // good
            System.out.println("test " + testnum++ + " passed");
        }
    }

    private static class MyCallbackHandler implements CallbackHandler {

        private final boolean good;

        public MyCallbackHandler(boolean good) {
            this.good = good;
        }

        public void handle(Callback[] callbacks)
                throws IOException, UnsupportedCallbackException {
            for (int i = 0; i < callbacks.length; i++) {
                if (callbacks[i] instanceof NameCallback) {
                    NameCallback nc = (NameCallback) callbacks[i];
                    if (good) {
                        nc.setName(OptionTest.ALIAS);
                    } else {
                        nc.setName("FOO");
                    }
                } else if (callbacks[i] instanceof PasswordCallback) {
                    PasswordCallback pc = (PasswordCallback) callbacks[i];

                    // this is dependent on KeyStoreLoginModule
                    if (pc.getPrompt().startsWith("Keystore password: ")) {
                        pc.setPassword(OptionTest.STORE_PASS);
                    } else if (pc.getPrompt().startsWith("Private key")) {
                        pc.setPassword(OptionTest.KEY_PASS);
                    }
                } else if (callbacks[i] instanceof ConfirmationCallback) {
                    ConfirmationCallback confirmation =
                        (ConfirmationCallback) callbacks[i];
                    // this is dependent on KeyStoreLoginModule confirmation
                    confirmation.setSelectedIndex(ConfirmationCallback.OK);
                }
            }
        }
    }
}
