/*
 * Copyright (c) 2005, 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.  Oracle designates this
 * particular file as subject to the "Classpath" exception as provided
 * by Oracle in the LICENSE file that accompanied this code.
 *
 * 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.
 */

package sun.security.pkcs11;

import java.io.*;
import java.util.*;

import java.security.*;
import java.security.KeyStore.*;
import java.security.cert.X509Certificate;

import sun.security.pkcs11.wrapper.*;
import static sun.security.pkcs11.wrapper.PKCS11Constants.*;

/**
 * The Secmod class defines the interface to the native NSS
 * library and the configuration information it stores in its
 * secmod.db file.
 *
 * <p>Example code:
 * <pre>
 *   Secmod secmod = Secmod.getInstance();
 *   if (secmod.isInitialized() == false) {
 *       secmod.initialize("/home/myself/.mozilla", "/usr/sfw/lib/mozilla");
 *   }
 *
 *   Provider p = secmod.getModule(ModuleType.KEYSTORE).getProvider();
 *   KeyStore ks = KeyStore.getInstance("PKCS11", p);
 *   ks.load(null, password);
 * </pre>
 *
 * @since   1.6
 * @author  Andreas Sterbenz
 */
public final class Secmod {

    private final static boolean DEBUG = false;

    private final static Secmod INSTANCE;

    static {
        sun.security.pkcs11.wrapper.PKCS11.loadNative();
        INSTANCE = new Secmod();
    }

    private final static String NSS_LIB_NAME = "nss3";

    private final static String SOFTTOKEN_LIB_NAME = "softokn3";

    private final static String TRUST_LIB_NAME = "nssckbi";

    // handle to be passed to the native code, 0 means not initialized
    private long nssHandle;

    // whether this is a supported version of NSS
    private boolean supported;

    // list of the modules
    private List<Module> modules;

    private String configDir;

    private String nssLibDir;

    private Secmod() {
        // empty
    }

    /**
     * Return the singleton Secmod instance.
     */
    public static Secmod getInstance() {
        return INSTANCE;
    }

    private boolean isLoaded() {
        if (nssHandle == 0) {
            nssHandle = nssGetLibraryHandle(System.mapLibraryName(NSS_LIB_NAME));
            if (nssHandle != 0) {
                fetchVersions();
            }
        }
        return (nssHandle != 0);
    }

    private void fetchVersions() {
        supported = nssVersionCheck(nssHandle, "3.7");
    }

    /**
     * Test whether this Secmod has been initialized. Returns true
     * if NSS has been initialized using either the initialize() method
     * or by directly calling the native NSS APIs. The latter may be
     * the case if the current process contains components that use
     * NSS directly.
     *
     * @throws IOException if an incompatible version of NSS
     *   has been loaded
     */
    public synchronized boolean isInitialized() throws IOException {
        // NSS does not allow us to check if it is initialized already
        // assume that if it is loaded it is also initialized
        if (isLoaded() == false) {
            return false;
        }
        if (supported == false) {
            throw new IOException
                ("An incompatible version of NSS is already loaded, "
                + "3.7 or later required");
        }
        return true;
    }

    String getConfigDir() {
        return configDir;
    }

    String getLibDir() {
        return nssLibDir;
    }

    /**
     * Initialize this Secmod.
     *
     * @param configDir the directory containing the NSS configuration
     *   files such as secmod.db
     * @param nssLibDir the directory containing the NSS libraries
     *   (libnss3.so or nss3.dll) or null if the library is on
     *   the system default shared library path
     *
     * @throws IOException if NSS has already been initialized,
     *   the specified directories are invalid, or initialization
     *   fails for any other reason
     */
    public void initialize(String configDir, String nssLibDir)
            throws IOException {
        initialize(DbMode.READ_WRITE, configDir, nssLibDir);
    }

    public synchronized void initialize(DbMode dbMode, String configDir, String nssLibDir)
            throws IOException {
        if (isInitialized()) {
            throw new IOException("NSS is already initialized");
        }

        if (dbMode == null) {
            throw new NullPointerException();
        }
        if ((dbMode != DbMode.NO_DB) && (configDir == null)) {
            throw new NullPointerException();
        }
        String platformLibName = System.mapLibraryName("nss3");
        String platformPath;
        if (nssLibDir == null) {
            platformPath = platformLibName;
        } else {
            File base = new File(nssLibDir);
            if (base.isDirectory() == false) {
                throw new IOException("nssLibDir must be a directory:" + nssLibDir);
            }
            File platformFile = new File(base, platformLibName);
            if (platformFile.isFile() == false) {
                throw new FileNotFoundException(platformFile.getPath());
            }
            platformPath = platformFile.getPath();
        }

        if (configDir != null) {
            File configBase = new File(configDir);
            if (configBase.isDirectory() == false ) {
                throw new IOException("configDir must be a directory: " + configDir);
            }
            File secmodFile = new File(configBase, "secmod.db");
            if (secmodFile.isFile() == false) {
                throw new FileNotFoundException(secmodFile.getPath());
            }
        }

        if (DEBUG) System.out.println("lib: " + platformPath);
        nssHandle = nssLoadLibrary(platformPath);
        if (DEBUG) System.out.println("handle: " + nssHandle);
        fetchVersions();
        if (supported == false) {
            throw new IOException
                ("The specified version of NSS is incompatible, "
                + "3.7 or later required");
        }

        if (DEBUG) System.out.println("dir: " + configDir);
        boolean initok = nssInit(dbMode.functionName, nssHandle, configDir);
        if (DEBUG) System.out.println("init: " + initok);
        if (initok == false) {
            throw new IOException("NSS initialization failed");
        }

        this.configDir = configDir;
        this.nssLibDir = nssLibDir;
    }

    /**
     * Return an immutable list of all available modules.
     *
     * @throws IllegalStateException if this Secmod is misconfigured
     *   or not initialized
     */
    public synchronized List<Module> getModules() {
        try {
            if (isInitialized() == false) {
                throw new IllegalStateException("NSS not initialized");
            }
        } catch (IOException e) {
            // IOException if misconfigured
            throw new IllegalStateException(e);
        }
        if (modules == null) {
            List<Module> modules = (List<Module>)nssGetModuleList(nssHandle);
            this.modules = Collections.unmodifiableList(modules);
        }
        return modules;
    }

    private static byte[] getDigest(X509Certificate cert, String algorithm) {
        try {
            MessageDigest md = MessageDigest.getInstance(algorithm);
            return md.digest(cert.getEncoded());
        } catch (GeneralSecurityException e) {
            throw new ProviderException(e);
        }
    }

    boolean isTrusted(X509Certificate cert, TrustType trustType) {
        Bytes bytes = new Bytes(getDigest(cert, "SHA-1"));
        TrustAttributes attr = getModuleTrust(ModuleType.KEYSTORE, bytes);
        if (attr == null) {
            attr = getModuleTrust(ModuleType.FIPS, bytes);
            if (attr == null) {
                attr = getModuleTrust(ModuleType.TRUSTANCHOR, bytes);
            }
        }
        return (attr == null) ? false : attr.isTrusted(trustType);
    }

    private TrustAttributes getModuleTrust(ModuleType type, Bytes bytes) {
        Module module = getModule(type);
        TrustAttributes t = (module == null) ? null : module.getTrust(bytes);
        return t;
    }

    /**
     * Constants describing the different types of NSS modules.
     * For this API, NSS modules are classified as either one
     * of the internal modules delivered as part of NSS or
     * as an external module provided by a 3rd party.
     */
    public static enum ModuleType {
        /**
         * The NSS Softtoken crypto module. This is the first
         * slot of the softtoken object.
         * This module provides
         * implementations for cryptographic algorithms but no KeyStore.
         */
        CRYPTO,
        /**
         * The NSS Softtoken KeyStore module. This is the second
         * slot of the softtoken object.
         * This module provides
         * implementations for cryptographic algorithms (after login)
         * and the KeyStore.
         */
        KEYSTORE,
        /**
         * The NSS Softtoken module in FIPS mode. Note that in FIPS mode the
         * softtoken presents only one slot, not separate CRYPTO and KEYSTORE
         * slots as in non-FIPS mode.
         */
        FIPS,
        /**
         * The NSS builtin trust anchor module. This is the
         * NSSCKBI object. It provides no crypto functions.
         */
        TRUSTANCHOR,
        /**
         * An external module.
         */
        EXTERNAL,
    }

    /**
     * Returns the first module of the specified type. If no such
     * module exists, this method returns null.
     *
     * @throws IllegalStateException if this Secmod is misconfigured
     *   or not initialized
     */
    public Module getModule(ModuleType type) {
        for (Module module : getModules()) {
            if (module.getType() == type) {
                return module;
            }
        }
        return null;
    }

    static final String TEMPLATE_EXTERNAL =
        "library = %s\n"
        + "name = \"%s\"\n"
        + "slotListIndex = %d\n";

    static final String TEMPLATE_TRUSTANCHOR =
        "library = %s\n"
        + "name = \"NSS Trust Anchors\"\n"
        + "slotListIndex = 0\n"
        + "enabledMechanisms = { KeyStore }\n"
        + "nssUseSecmodTrust = true\n";

    static final String TEMPLATE_CRYPTO =
        "library = %s\n"
        + "name = \"NSS SoftToken Crypto\"\n"
        + "slotListIndex = 0\n"
        + "disabledMechanisms = { KeyStore }\n";

    static final String TEMPLATE_KEYSTORE =
        "library = %s\n"
        + "name = \"NSS SoftToken KeyStore\"\n"
        + "slotListIndex = 1\n"
        + "nssUseSecmodTrust = true\n";

    static final String TEMPLATE_FIPS =
        "library = %s\n"
        + "name = \"NSS FIPS SoftToken\"\n"
        + "slotListIndex = 0\n"
        + "nssUseSecmodTrust = true\n";

    /**
     * A representation of one PKCS#11 slot in a PKCS#11 module.
     */
    public static final class Module {
        // name of the native library
        final String libraryName;
        // descriptive name used by NSS
        final String commonName;
        final int slot;
        final ModuleType type;

        private String config;
        private SunPKCS11 provider;

        // trust attributes. Used for the KEYSTORE and TRUSTANCHOR modules only
        private Map<Bytes,TrustAttributes> trust;

        Module(String libraryName, String commonName, boolean fips, int slot) {
            ModuleType type;
            if ((libraryName == null) || (libraryName.length() == 0)) {
                // must be softtoken
                libraryName = System.mapLibraryName(SOFTTOKEN_LIB_NAME);
                if (fips == false) {
                    type = (slot == 0) ? ModuleType.CRYPTO : ModuleType.KEYSTORE;
                } else {
                    type = ModuleType.FIPS;
                    if (slot != 0) {
                        throw new RuntimeException
                            ("Slot index should be 0 for FIPS slot");
                    }
                }
            } else {
                if (libraryName.endsWith(System.mapLibraryName(TRUST_LIB_NAME))
                        || commonName.equals("Builtin Roots Module")) {
                    type = ModuleType.TRUSTANCHOR;
                } else {
                    type = ModuleType.EXTERNAL;
                }
                if (fips) {
                    throw new RuntimeException("FIPS flag set for non-internal "
                        + "module: " + libraryName + ", " + commonName);
                }
            }
            this.libraryName = libraryName;
            this.commonName = commonName;
            this.slot = slot;
            this.type = type;
            initConfiguration();
        }

        private void initConfiguration() {
            switch (type) {
            case EXTERNAL:
                config = String.format(TEMPLATE_EXTERNAL, libraryName,
                                            commonName + " " + slot, slot);
                break;
            case CRYPTO:
                config = String.format(TEMPLATE_CRYPTO, libraryName);
                break;
            case KEYSTORE:
                config = String.format(TEMPLATE_KEYSTORE, libraryName);
                break;
            case FIPS:
                config = String.format(TEMPLATE_FIPS, libraryName);
                break;
            case TRUSTANCHOR:
                config = String.format(TEMPLATE_TRUSTANCHOR, libraryName);
                break;
            default:
                throw new RuntimeException("Unknown module type: " + type);
            }
        }

        /**
         * Get the configuration for this module. This is a string
         * in the SunPKCS11 configuration format. It can be
         * customized with additional options and then made
         * current using the setConfiguration() method.
         */
        @Deprecated
        public synchronized String getConfiguration() {
            return config;
        }

        /**
         * Set the configuration for this module.
         *
         * @throws IllegalStateException if the associated provider
         *   instance has already been created.
         */
        @Deprecated
        public synchronized void setConfiguration(String config) {
            if (provider != null) {
                throw new IllegalStateException("Provider instance already created");
            }
            this.config = config;
        }

        /**
         * Return the pathname of the native library that implements
         * this module. For example, /usr/lib/libpkcs11.so.
         */
        public String getLibraryName() {
            return libraryName;
        }

        /**
         * Returns the type of this module.
         */
        public ModuleType getType() {
            return type;
        }

        /**
         * Returns the provider instance that is associated with this
         * module. The first call to this method creates the provider
         * instance.
         */
        @Deprecated
        public synchronized Provider getProvider() {
            if (provider == null) {
                provider = newProvider();
            }
            return provider;
        }

        synchronized boolean hasInitializedProvider() {
            return provider != null;
        }

        void setProvider(SunPKCS11 p) {
            if (provider != null) {
                throw new ProviderException("Secmod provider already initialized");
            }
            provider = p;
        }

        private SunPKCS11 newProvider() {
            try {
                InputStream in = new ByteArrayInputStream(config.getBytes("UTF8"));
                return new SunPKCS11(in);
            } catch (Exception e) {
                // XXX
                throw new ProviderException(e);
            }
        }

        synchronized void setTrust(Token token, X509Certificate cert) {
            Bytes bytes = new Bytes(getDigest(cert, "SHA-1"));
            TrustAttributes attr = getTrust(bytes);
            if (attr == null) {
                attr = new TrustAttributes(token, cert, bytes, CKT_NETSCAPE_TRUSTED_DELEGATOR);
                trust.put(bytes, attr);
            } else {
                // does it already have the correct trust settings?
                if (attr.isTrusted(TrustType.ALL) == false) {
                    // XXX not yet implemented
                    throw new ProviderException("Cannot change existing trust attributes");
                }
            }
        }

        TrustAttributes getTrust(Bytes hash) {
            if (trust == null) {
                // If provider is not set, create a temporary provider to
                // retrieve the trust information. This can happen if we need
                // to get the trust information for the trustanchor module
                // because we need to look for user customized settings in the
                // keystore module (which may not have a provider created yet).
                // Creating a temporary provider and then dropping it on the
                // floor immediately is flawed, but it's the best we can do
                // for now.
                synchronized (this) {
                    SunPKCS11 p = provider;
                    if (p == null) {
                        p = newProvider();
                    }
                    try {
                        trust = Secmod.getTrust(p);
                    } catch (PKCS11Exception e) {
                        throw new RuntimeException(e);
                    }
                }
            }
            return trust.get(hash);
        }

        public String toString() {
            return
            commonName + " (" + type + ", " + libraryName + ", slot " + slot + ")";
        }

    }

    /**
     * Constants representing NSS trust categories.
     */
    public static enum TrustType {
        /** Trusted for all purposes */
        ALL,
        /** Trusted for SSL client authentication */
        CLIENT_AUTH,
        /** Trusted for SSL server authentication */
        SERVER_AUTH,
        /** Trusted for code signing */
        CODE_SIGNING,
        /** Trusted for email protection */
        EMAIL_PROTECTION,
    }

    public static enum DbMode {
        READ_WRITE("NSS_InitReadWrite"),
        READ_ONLY ("NSS_Init"),
        NO_DB     ("NSS_NoDB_Init");

        final String functionName;
        DbMode(String functionName) {
            this.functionName = functionName;
        }
    }

    /**
     * A LoadStoreParameter for use with the NSS Softtoken or
     * NSS TrustAnchor KeyStores.
     * <p>
     * It allows the set of trusted certificates that are returned by
     * the KeyStore to be specified.
     */
    public static final class KeyStoreLoadParameter implements LoadStoreParameter {
        final TrustType trustType;
        final ProtectionParameter protection;
        public KeyStoreLoadParameter(TrustType trustType, char[] password) {
            this(trustType, new PasswordProtection(password));

        }
        public KeyStoreLoadParameter(TrustType trustType, ProtectionParameter prot) {
            if (trustType == null) {
                throw new NullPointerException("trustType must not be null");
            }
            this.trustType = trustType;
            this.protection = prot;
        }
        public ProtectionParameter getProtectionParameter() {
            return protection;
        }
        public TrustType getTrustType() {
            return trustType;
        }
    }

    static class TrustAttributes {
        final long handle;
        final long clientAuth, serverAuth, codeSigning, emailProtection;
        final byte[] shaHash;
        TrustAttributes(Token token, X509Certificate cert, Bytes bytes, long trustValue) {
            Session session = null;
            try {
                session = token.getOpSession();
                // XXX use KeyStore TrustType settings to determine which
                // attributes to set
                CK_ATTRIBUTE[] attrs = new CK_ATTRIBUTE[] {
                    new CK_ATTRIBUTE(CKA_TOKEN, true),
                    new CK_ATTRIBUTE(CKA_CLASS, CKO_NETSCAPE_TRUST),
                    new CK_ATTRIBUTE(CKA_NETSCAPE_TRUST_SERVER_AUTH, trustValue),
                    new CK_ATTRIBUTE(CKA_NETSCAPE_TRUST_CODE_SIGNING, trustValue),
                    new CK_ATTRIBUTE(CKA_NETSCAPE_TRUST_EMAIL_PROTECTION, trustValue),
                    new CK_ATTRIBUTE(CKA_NETSCAPE_TRUST_CLIENT_AUTH, trustValue),
                    new CK_ATTRIBUTE(CKA_NETSCAPE_CERT_SHA1_HASH, bytes.b),
                    new CK_ATTRIBUTE(CKA_NETSCAPE_CERT_MD5_HASH, getDigest(cert, "MD5")),
                    new CK_ATTRIBUTE(CKA_ISSUER, cert.getIssuerX500Principal().getEncoded()),
                    new CK_ATTRIBUTE(CKA_SERIAL_NUMBER, cert.getSerialNumber().toByteArray()),
                    // XXX per PKCS#11 spec, the serial number should be in ASN.1
                };
                handle = token.p11.C_CreateObject(session.id(), attrs);
                shaHash = bytes.b;
                clientAuth = trustValue;
                serverAuth = trustValue;
                codeSigning = trustValue;
                emailProtection = trustValue;
            } catch (PKCS11Exception e) {
                throw new ProviderException("Could not create trust object", e);
            } finally {
                token.releaseSession(session);
            }
        }
        TrustAttributes(Token token, Session session, long handle)
                        throws PKCS11Exception {
            this.handle = handle;
            CK_ATTRIBUTE[] attrs = new CK_ATTRIBUTE[] {
                new CK_ATTRIBUTE(CKA_NETSCAPE_TRUST_SERVER_AUTH),
                new CK_ATTRIBUTE(CKA_NETSCAPE_TRUST_CODE_SIGNING),
                new CK_ATTRIBUTE(CKA_NETSCAPE_TRUST_EMAIL_PROTECTION),
                new CK_ATTRIBUTE(CKA_NETSCAPE_CERT_SHA1_HASH),
            };

            token.p11.C_GetAttributeValue(session.id(), handle, attrs);
            serverAuth = attrs[0].getLong();
            codeSigning = attrs[1].getLong();
            emailProtection = attrs[2].getLong();
            shaHash = attrs[3].getByteArray();

            attrs = new CK_ATTRIBUTE[] {
                new CK_ATTRIBUTE(CKA_NETSCAPE_TRUST_CLIENT_AUTH),
            };
            long c;
            try {
                token.p11.C_GetAttributeValue(session.id(), handle, attrs);
                c = attrs[0].getLong();
            } catch (PKCS11Exception e) {
                // trust anchor module does not support this attribute
                c = serverAuth;
            }
            clientAuth = c;
        }
        Bytes getHash() {
            return new Bytes(shaHash);
        }
        boolean isTrusted(TrustType type) {
            switch (type) {
            case CLIENT_AUTH:
                return isTrusted(clientAuth);
            case SERVER_AUTH:
                return isTrusted(serverAuth);
            case CODE_SIGNING:
                return isTrusted(codeSigning);
            case EMAIL_PROTECTION:
                return isTrusted(emailProtection);
            case ALL:
                return isTrusted(TrustType.CLIENT_AUTH)
                    && isTrusted(TrustType.SERVER_AUTH)
                    && isTrusted(TrustType.CODE_SIGNING)
                    && isTrusted(TrustType.EMAIL_PROTECTION);
            default:
                return false;
            }
        }

        private boolean isTrusted(long l) {
            // XXX CKT_TRUSTED?
            return (l == CKT_NETSCAPE_TRUSTED_DELEGATOR);
        }

    }

    private static class Bytes {
        final byte[] b;
        Bytes(byte[] b) {
            this.b = b;
        }
        public int hashCode() {
            return Arrays.hashCode(b);
        }
        public boolean equals(Object o) {
            if (this == o) {
                return true;
            }
            if (o instanceof Bytes == false) {
                return false;
            }
            Bytes other = (Bytes)o;
            return Arrays.equals(this.b, other.b);
        }
    }

    private static Map<Bytes,TrustAttributes> getTrust(SunPKCS11 provider)
            throws PKCS11Exception {
        Map<Bytes,TrustAttributes> trustMap = new HashMap<Bytes,TrustAttributes>();
        Token token = provider.getToken();
        Session session = null;
        try {
            session = token.getOpSession();
            int MAX_NUM = 8192;
            CK_ATTRIBUTE[] attrs = new CK_ATTRIBUTE[] {
                new CK_ATTRIBUTE(CKA_CLASS, CKO_NETSCAPE_TRUST),
            };
            token.p11.C_FindObjectsInit(session.id(), attrs);
            long[] handles = token.p11.C_FindObjects(session.id(), MAX_NUM);
            token.p11.C_FindObjectsFinal(session.id());
            if (DEBUG) System.out.println("handles: " + handles.length);

            for (long handle : handles) {
                TrustAttributes trust = new TrustAttributes(token, session, handle);
                trustMap.put(trust.getHash(), trust);
            }
        } finally {
            token.releaseSession(session);
        }
        return trustMap;
    }

    private static native long nssGetLibraryHandle(String libraryName);

    private static native long nssLoadLibrary(String name) throws IOException;

    private static native boolean nssVersionCheck(long handle, String minVersion);

    private static native boolean nssInit(String functionName, long handle, String configDir);

    private static native Object nssGetModuleList(long handle);

}
