/*
 * Copyright 2003-2006 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.  Sun designates this
 * particular file as subject to the "Classpath" exception as provided
 * by Sun 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 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.
 */

package sun.security.pkcs11;

import java.io.*;
import static java.io.StreamTokenizer.*;
import java.math.BigInteger;
import java.util.*;

import java.security.*;

import sun.security.action.GetPropertyAction;
import sun.security.util.PropertyExpander;

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

import static sun.security.pkcs11.TemplateManager.*;

/**
 * Configuration container and file parsing.
 *
 * @author  Andreas Sterbenz
 * @since   1.5
 */
final class Config {

    static final int ERR_HALT       = 1;
    static final int ERR_IGNORE_ALL = 2;
    static final int ERR_IGNORE_LIB = 3;

    // same as allowSingleThreadedModules but controlled via a system property
    // and applied to all providers. if set to false, no SunPKCS11 instances
    // will accept single threaded modules regardless of the setting in their
    // config files.
    private static final boolean staticAllowSingleThreadedModules;

    static {
        String p = "sun.security.pkcs11.allowSingleThreadedModules";
        String s = AccessController.doPrivileged(new GetPropertyAction(p));
        if ("false".equalsIgnoreCase(s)) {
            staticAllowSingleThreadedModules = false;
        } else {
            staticAllowSingleThreadedModules = true;
        }
    }

    // temporary storage for configurations
    // needed because the SunPKCS11 needs to call the superclass constructor
    // in provider before accessing any instance variables
    private final static Map<String,Config> configMap =
                                        new HashMap<String,Config>();

    static Config getConfig(final String name, final InputStream stream) {
        Config config = configMap.get(name);
        if (config != null) {
            return config;
        }
        try {
            config = new Config(name, stream);
            configMap.put(name, config);
            return config;
        } catch (Exception e) {
            throw new ProviderException("Error parsing configuration", e);
        }
    }

    static Config removeConfig(String name) {
        return configMap.remove(name);
    }

    private final static boolean DEBUG = false;

    private static void debug(Object o) {
        if (DEBUG) {
            System.out.println(o);
        }
    }

    // Reader and StringTokenizer used during parsing
    private Reader reader;

    private StreamTokenizer st;

    private Set<String> parsedKeywords;

    // name suffix of the provider
    private String name;

    // name of the PKCS#11 library
    private String library;

    // description to pass to the provider class
    private String description;

    // slotID of the slot to use
    private int slotID = -1;

    // slot to use, specified as index in the slotlist
    private int slotListIndex = -1;

    // set of enabled mechanisms (or null to use default)
    private Set<Long> enabledMechanisms;

    // set of disabled mechanisms
    private Set<Long> disabledMechanisms;

    // whether to print debug info during startup
    private boolean showInfo = false;

    // template manager, initialized from parsed attributes
    private TemplateManager templateManager;

    // how to handle error during startup, one of ERR_
    private int handleStartupErrors = ERR_HALT;

    // flag indicating whether the P11KeyStore should
    // be more tolerant of input parameters
    private boolean keyStoreCompatibilityMode = true;

    // flag indicating whether we need to explicitly cancel operations
    // see Token
    private boolean explicitCancel = true;

    // how often to test for token insertion, if no token is present
    private int insertionCheckInterval = 2000;

    // flag inidicating whether to omit the call to C_Initialize()
    // should be used only if we are running within a process that
    // has already called it (e.g. Plugin inside of Mozilla/NSS)
    private boolean omitInitialize = false;

    // whether to allow modules that only support single threaded access.
    // they cannot be used safely from multiple PKCS#11 consumers in the
    // same process, for example NSS and SunPKCS11
    private boolean allowSingleThreadedModules = true;

    // name of the C function that returns the PKCS#11 functionlist
    // This option primarily exists for the deprecated
    // Secmod.Module.getProvider() method.
    private String functionList = "C_GetFunctionList";

    // whether to use NSS secmod mode. Implicitly set if nssLibraryDirectory,
    // nssSecmodDirectory, or nssModule is specified.
    private boolean nssUseSecmod;

    // location of the NSS library files (libnss3.so, etc.)
    private String nssLibraryDirectory;

    // location of secmod.db
    private String nssSecmodDirectory;

    // which NSS module to use
    private String nssModule;

    private Secmod.DbMode nssDbMode = Secmod.DbMode.READ_WRITE;

    // Whether the P11KeyStore should specify the CKA_NETSCAPE_DB attribute
    // when creating private keys. Only valid if nssUseSecmod is true.
    private boolean nssNetscapeDbWorkaround = true;

    // Special init argument string for the NSS softtoken.
    // This is used when using the NSS softtoken directly without secmod mode.
    private String nssArgs;

    // whether to use NSS trust attributes for the KeyStore of this provider
    // this option is for internal use by the SunPKCS11 code only and
    // works only for NSS providers created via the Secmod API
    private boolean nssUseSecmodTrust = false;

    private Config(String filename, InputStream in) throws IOException {
        if (in == null) {
            if (filename.startsWith("--")) {
                // inline config
                String config = filename.substring(2).replace("\\n", "\n");
                reader = new StringReader(config);
            } else {
                in = new FileInputStream(expand(filename));
            }
        }
        if (reader == null) {
            reader = new BufferedReader(new InputStreamReader(in));
        }
        parsedKeywords = new HashSet<String>();
        st = new StreamTokenizer(reader);
        setupTokenizer();
        parse();
    }

    String getName() {
        return name;
    }

    String getLibrary() {
        return library;
    }

    String getDescription() {
        if (description != null) {
            return description;
        }
        return "SunPKCS11-" + name + " using library " + library;
    }

    int getSlotID() {
        return slotID;
    }

    int getSlotListIndex() {
        if ((slotID == -1) && (slotListIndex == -1)) {
            // if neither is set, default to first slot
            return 0;
        } else {
            return slotListIndex;
        }
    }

    boolean getShowInfo() {
        return (SunPKCS11.debug != null) || showInfo;
    }

    TemplateManager getTemplateManager() {
        if (templateManager == null) {
            templateManager = new TemplateManager();
        }
        return templateManager;
    }

    boolean isEnabled(long m) {
        if (enabledMechanisms != null) {
            return enabledMechanisms.contains(Long.valueOf(m));
        }
        if (disabledMechanisms != null) {
            return !disabledMechanisms.contains(Long.valueOf(m));
        }
        return true;
    }

    int getHandleStartupErrors() {
        return handleStartupErrors;
    }

    boolean getKeyStoreCompatibilityMode() {
        return keyStoreCompatibilityMode;
    }

    boolean getExplicitCancel() {
        return explicitCancel;
    }

    int getInsertionCheckInterval() {
        return insertionCheckInterval;
    }

    boolean getOmitInitialize() {
        return omitInitialize;
    }

    boolean getAllowSingleThreadedModules() {
        return staticAllowSingleThreadedModules && allowSingleThreadedModules;
    }

    String getFunctionList() {
        return functionList;
    }

    boolean getNssUseSecmod() {
        return nssUseSecmod;
    }

    String getNssLibraryDirectory() {
        return nssLibraryDirectory;
    }

    String getNssSecmodDirectory() {
        return nssSecmodDirectory;
    }

    String getNssModule() {
        return nssModule;
    }

    Secmod.DbMode getNssDbMode() {
        return nssDbMode;
    }

    public boolean getNssNetscapeDbWorkaround() {
        return nssUseSecmod && nssNetscapeDbWorkaround;
    }

    String getNssArgs() {
        return nssArgs;
    }

    boolean getNssUseSecmodTrust() {
        return nssUseSecmodTrust;
    }

    private static String expand(final String s) throws IOException {
        try {
            return PropertyExpander.expand(s);
        } catch (Exception e) {
            throw new RuntimeException(e.getMessage());
        }
    }

    private void setupTokenizer() {
        st.resetSyntax();
        st.wordChars('a', 'z');
        st.wordChars('A', 'Z');
        st.wordChars('0', '9');
        st.wordChars(':', ':');
        st.wordChars('.', '.');
        st.wordChars('_', '_');
        st.wordChars('-', '-');
        st.wordChars('/', '/');
        st.wordChars('\\', '\\');
        st.wordChars('$', '$');
        st.wordChars('{', '{'); // need {} for property subst
        st.wordChars('}', '}');
        st.wordChars('*', '*');
        // XXX check ASCII table and add all other characters except special

        // special: #="(),
        st.whitespaceChars(0, ' ');
        st.commentChar('#');
        st.eolIsSignificant(true);
        st.quoteChar('\"');
    }

    private ConfigurationException excToken(String msg) {
        return new ConfigurationException(msg + " " + st);
    }

    private ConfigurationException excLine(String msg) {
        return new ConfigurationException(msg + ", line " + st.lineno());
    }

    private void parse() throws IOException {
        while (true) {
            int token = nextToken();
            if (token == TT_EOF) {
                break;
            }
            if (token == TT_EOL) {
                continue;
            }
            if (token != TT_WORD) {
                throw excToken("Unexpected token:");
            }
            String word = st.sval;
            if (word.equals("name")) {
                name = parseStringEntry(word);
            } else if (word.equals("library")) {
                library = parseLibrary(word);
            } else if (word.equals("description")) {
                parseDescription(word);
            } else if (word.equals("slot")) {
                parseSlotID(word);
            } else if (word.equals("slotListIndex")) {
                parseSlotListIndex(word);
            } else if (word.equals("enabledMechanisms")) {
                parseEnabledMechanisms(word);
            } else if (word.equals("disabledMechanisms")) {
                parseDisabledMechanisms(word);
            } else if (word.equals("attributes")) {
                parseAttributes(word);
            } else if (word.equals("handleStartupErrors")) {
                parseHandleStartupErrors(word);
            } else if (word.endsWith("insertionCheckInterval")) {
                insertionCheckInterval = parseIntegerEntry(word);
                if (insertionCheckInterval < 100) {
                    throw excLine(word + " must be at least 100 ms");
                }
            } else if (word.equals("showInfo")) {
                showInfo = parseBooleanEntry(word);
            } else if (word.equals("keyStoreCompatibilityMode")) {
                keyStoreCompatibilityMode = parseBooleanEntry(word);
            } else if (word.equals("explicitCancel")) {
                explicitCancel = parseBooleanEntry(word);
            } else if (word.equals("omitInitialize")) {
                omitInitialize = parseBooleanEntry(word);
            } else if (word.equals("allowSingleThreadedModules")) {
                allowSingleThreadedModules = parseBooleanEntry(word);
            } else if (word.equals("functionList")) {
                functionList = parseStringEntry(word);
            } else if (word.equals("nssUseSecmod")) {
                nssUseSecmod = parseBooleanEntry(word);
            } else if (word.equals("nssLibraryDirectory")) {
                nssLibraryDirectory = parseLibrary(word);
                nssUseSecmod = true;
            } else if (word.equals("nssSecmodDirectory")) {
                nssSecmodDirectory = expand(parseStringEntry(word));
                nssUseSecmod = true;
            } else if (word.equals("nssModule")) {
                nssModule = parseStringEntry(word);
                nssUseSecmod = true;
            } else if (word.equals("nssDbMode")) {
                String mode = parseStringEntry(word);
                if (mode.equals("readWrite")) {
                    nssDbMode = Secmod.DbMode.READ_WRITE;
                } else if (mode.equals("readOnly")) {
                    nssDbMode = Secmod.DbMode.READ_ONLY;
                } else if (mode.equals("noDb")) {
                    nssDbMode = Secmod.DbMode.NO_DB;
                } else {
                    throw excToken("nssDbMode must be one of readWrite, readOnly, and noDb:");
                }
                nssUseSecmod = true;
            } else if (word.equals("nssNetscapeDbWorkaround")) {
                nssNetscapeDbWorkaround = parseBooleanEntry(word);
                nssUseSecmod = true;
            } else if (word.equals("nssArgs")) {
                parseNSSArgs(word);
            } else if (word.equals("nssUseSecmodTrust")) {
                nssUseSecmodTrust = parseBooleanEntry(word);
            } else {
                throw new ConfigurationException
                        ("Unknown keyword '" + word + "', line " + st.lineno());
            }
            parsedKeywords.add(word);
        }
        reader.close();
        reader = null;
        st = null;
        parsedKeywords = null;
        if (name == null) {
            throw new ConfigurationException("name must be specified");
        }
        if (nssUseSecmod == false) {
            if (library == null) {
                throw new ConfigurationException("library must be specified");
            }
        } else {
            if (library != null) {
                throw new ConfigurationException
                    ("library must not be specified in NSS mode");
            }
            if ((slotID != -1) || (slotListIndex != -1)) {
                throw new ConfigurationException
                    ("slot and slotListIndex must not be specified in NSS mode");
            }
            if (nssArgs != null) {
                throw new ConfigurationException
                    ("nssArgs must not be specified in NSS mode");
            }
            if (nssUseSecmodTrust != false) {
                throw new ConfigurationException("nssUseSecmodTrust is an "
                    + "internal option and must not be specified in NSS mode");
            }
        }
    }

    //
    // Parsing helper methods
    //

    private int nextToken() throws IOException {
        int token = st.nextToken();
        debug(st);
        return token;
    }

    private void parseEquals() throws IOException {
        int token = nextToken();
        if (token != '=') {
            throw excToken("Expected '=', read");
        }
    }

    private void parseOpenBraces() throws IOException {
        while (true) {
            int token = nextToken();
            if (token == TT_EOL) {
                continue;
            }
            if ((token == TT_WORD) && st.sval.equals("{")) {
                return;
            }
            throw excToken("Expected '{', read");
        }
    }

    private boolean isCloseBraces(int token) {
        return (token == TT_WORD) && st.sval.equals("}");
    }

    private String parseWord() throws IOException {
        int token = nextToken();
        if (token != TT_WORD) {
            throw excToken("Unexpected value:");
        }
        return st.sval;
    }

    private String parseStringEntry(String keyword) throws IOException {
        checkDup(keyword);
        parseEquals();

        int token = nextToken();
        if (token != TT_WORD && token != '\"') {
            // not a word token nor a string enclosed by double quotes
            throw excToken("Unexpected value:");
        }
        String value = st.sval;

        debug(keyword + ": " + value);
        return value;
    }

    private boolean parseBooleanEntry(String keyword) throws IOException {
        checkDup(keyword);
        parseEquals();
        boolean value = parseBoolean();
        debug(keyword + ": " + value);
        return value;
    }

    private int parseIntegerEntry(String keyword) throws IOException {
        checkDup(keyword);
        parseEquals();
        int value = decodeNumber(parseWord());
        debug(keyword + ": " + value);
        return value;
    }

    private boolean parseBoolean() throws IOException {
        String val = parseWord();
        if (val.equals("true")) {
            return true;
        } else if (val.equals("false")) {
            return false;
        } else {
            throw excToken("Expected boolean value, read:");
        }
    }

    private String parseLine() throws IOException {
        String s = parseWord();
        while (true) {
            int token = nextToken();
            if ((token == TT_EOL) || (token == TT_EOF)) {
                break;
            }
            if (token != TT_WORD) {
                throw excToken("Unexpected value");
            }
            s = s + " " + st.sval;
        }
        return s;
    }

    private int decodeNumber(String str) throws IOException {
        try {
            if (str.startsWith("0x") || str.startsWith("0X")) {
                return Integer.parseInt(str.substring(2), 16);
            } else {
                return Integer.parseInt(str);
            }
        } catch (NumberFormatException e) {
            throw excToken("Expected number, read");
        }
    }

    private static boolean isNumber(String s) {
        if (s.length() == 0) {
            return false;
        }
        char ch = s.charAt(0);
        return ((ch >= '0') && (ch <= '9'));
    }

    private void parseComma() throws IOException {
        int token = nextToken();
        if (token != ',') {
            throw excToken("Expected ',', read");
        }
    }

    private static boolean isByteArray(String val) {
        return val.startsWith("0h");
    }

    private byte[] decodeByteArray(String str) throws IOException {
        if (str.startsWith("0h") == false) {
            throw excToken("Expected byte array value, read");
        }
        str = str.substring(2);
        // XXX proper hex parsing
        try {
            return new BigInteger(str, 16).toByteArray();
        } catch (NumberFormatException e) {
            throw excToken("Expected byte array value, read");
        }
    }

    private void checkDup(String keyword) throws IOException {
        if (parsedKeywords.contains(keyword)) {
            throw excLine(keyword + " must only be specified once");
        }
    }

    //
    // individual entry parsing methods
    //

    private String parseLibrary(String keyword) throws IOException {
        checkDup(keyword);
        parseEquals();
        String lib = parseLine();
        lib = expand(lib);
        int i = lib.indexOf("/$ISA/");
        if (i != -1) {
            // replace "/$ISA/" with "/sparcv9/" on 64-bit Solaris SPARC
            // and with "/amd64/" on Solaris AMD64.
            // On all other platforms, just turn it into a "/"
            String osName = System.getProperty("os.name", "");
            String osArch = System.getProperty("os.arch", "");
            String prefix = lib.substring(0, i);
            String suffix = lib.substring(i + 5);
            if (osName.equals("SunOS") && osArch.equals("sparcv9")) {
                lib = prefix + "/sparcv9" + suffix;
            } else if (osName.equals("SunOS") && osArch.equals("amd64")) {
                lib = prefix + "/amd64" + suffix;
            } else {
                lib = prefix + suffix;
            }
        }
        debug(keyword + ": " + lib);
        return lib;
    }

    private void parseDescription(String keyword) throws IOException {
        checkDup(keyword);
        parseEquals();
        description = parseLine();
        debug("description: " + description);
    }

    private void parseSlotID(String keyword) throws IOException {
        if (slotID >= 0) {
            throw excLine("Duplicate slot definition");
        }
        if (slotListIndex >= 0) {
            throw excLine
                ("Only one of slot and slotListIndex must be specified");
        }
        parseEquals();
        String slotString = parseWord();
        slotID = decodeNumber(slotString);
        debug("slot: " + slotID);
    }

    private void parseSlotListIndex(String keyword) throws IOException {
        if (slotListIndex >= 0) {
            throw excLine("Duplicate slotListIndex definition");
        }
        if (slotID >= 0) {
            throw excLine
                ("Only one of slot and slotListIndex must be specified");
        }
        parseEquals();
        String slotString = parseWord();
        slotListIndex = decodeNumber(slotString);
        debug("slotListIndex: " + slotListIndex);
    }

    private void parseEnabledMechanisms(String keyword) throws IOException {
        enabledMechanisms = parseMechanisms(keyword);
    }

    private void parseDisabledMechanisms(String keyword) throws IOException {
        disabledMechanisms = parseMechanisms(keyword);
    }

    private Set<Long> parseMechanisms(String keyword) throws IOException {
        checkDup(keyword);
        Set<Long> mechs = new HashSet<Long>();
        parseEquals();
        parseOpenBraces();
        while (true) {
            int token = nextToken();
            if (isCloseBraces(token)) {
                break;
            }
            if (token == TT_EOL) {
                continue;
            }
            if (token != TT_WORD) {
                throw excToken("Expected mechanism, read");
            }
            long mech = parseMechanism(st.sval);
            mechs.add(Long.valueOf(mech));
        }
        if (DEBUG) {
            System.out.print("mechanisms: [");
            for (Long mech : mechs) {
                System.out.print(Functions.getMechanismName(mech));
                System.out.print(", ");
            }
            System.out.println("]");
        }
        return mechs;
    }

    private long parseMechanism(String mech) throws IOException {
        if (isNumber(mech)) {
            return decodeNumber(mech);
        } else {
            try {
                return Functions.getMechanismId(mech);
            } catch (IllegalArgumentException e) {
                throw excLine("Unknown mechanism: " + mech);
            }
        }
    }

    private void parseAttributes(String keyword) throws IOException {
        if (templateManager == null) {
            templateManager = new TemplateManager();
        }
        int token = nextToken();
        if (token == '=') {
            String s = parseWord();
            if (s.equals("compatibility") == false) {
                throw excLine("Expected 'compatibility', read " + s);
            }
            setCompatibilityAttributes();
            return;
        }
        if (token != '(') {
            throw excToken("Expected '(' or '=', read");
        }
        String op = parseOperation();
        parseComma();
        long objectClass = parseObjectClass();
        parseComma();
        long keyAlg = parseKeyAlgorithm();
        token = nextToken();
        if (token != ')') {
            throw excToken("Expected ')', read");
        }
        parseEquals();
        parseOpenBraces();
        List<CK_ATTRIBUTE> attributes = new ArrayList<CK_ATTRIBUTE>();
        while (true) {
            token = nextToken();
            if (isCloseBraces(token)) {
                break;
            }
            if (token == TT_EOL) {
                continue;
            }
            if (token != TT_WORD) {
                throw excToken("Expected mechanism, read");
            }
            String attributeName = st.sval;
            long attributeId = decodeAttributeName(attributeName);
            parseEquals();
            String attributeValue = parseWord();
            attributes.add(decodeAttributeValue(attributeId, attributeValue));
        }
        templateManager.addTemplate
                (op, objectClass, keyAlg, attributes.toArray(CK_A0));
    }

    private void setCompatibilityAttributes() {
        // all secret keys
        templateManager.addTemplate(O_ANY, CKO_SECRET_KEY, PCKK_ANY,
        new CK_ATTRIBUTE[] {
            TOKEN_FALSE,
            SENSITIVE_FALSE,
            EXTRACTABLE_TRUE,
            ENCRYPT_TRUE,
            DECRYPT_TRUE,
            WRAP_TRUE,
            UNWRAP_TRUE,
        });

        // generic secret keys are special
        // They are used as MAC keys plus for the SSL/TLS (pre)master secrets
        templateManager.addTemplate(O_ANY, CKO_SECRET_KEY, CKK_GENERIC_SECRET,
        new CK_ATTRIBUTE[] {
            SIGN_TRUE,
            VERIFY_TRUE,
            ENCRYPT_NULL,
            DECRYPT_NULL,
            WRAP_NULL,
            UNWRAP_NULL,
            DERIVE_TRUE,
        });

        // all private and public keys
        templateManager.addTemplate(O_ANY, CKO_PRIVATE_KEY, PCKK_ANY,
        new CK_ATTRIBUTE[] {
            TOKEN_FALSE,
            SENSITIVE_FALSE,
            EXTRACTABLE_TRUE,
        });
        templateManager.addTemplate(O_ANY, CKO_PUBLIC_KEY, PCKK_ANY,
        new CK_ATTRIBUTE[] {
            TOKEN_FALSE,
        });

        // additional attributes for RSA private keys
        templateManager.addTemplate(O_ANY, CKO_PRIVATE_KEY, CKK_RSA,
        new CK_ATTRIBUTE[] {
            DECRYPT_TRUE,
            SIGN_TRUE,
            SIGN_RECOVER_TRUE,
            UNWRAP_TRUE,
        });
        // additional attributes for RSA public keys
        templateManager.addTemplate(O_ANY, CKO_PUBLIC_KEY, CKK_RSA,
        new CK_ATTRIBUTE[] {
            ENCRYPT_TRUE,
            VERIFY_TRUE,
            VERIFY_RECOVER_TRUE,
            WRAP_TRUE,
        });

        // additional attributes for DSA private keys
        templateManager.addTemplate(O_ANY, CKO_PRIVATE_KEY, CKK_DSA,
        new CK_ATTRIBUTE[] {
            SIGN_TRUE,
        });
        // additional attributes for DSA public keys
        templateManager.addTemplate(O_ANY, CKO_PUBLIC_KEY, CKK_DSA,
        new CK_ATTRIBUTE[] {
            VERIFY_TRUE,
        });

        // additional attributes for DH private keys
        templateManager.addTemplate(O_ANY, CKO_PRIVATE_KEY, CKK_DH,
        new CK_ATTRIBUTE[] {
            DERIVE_TRUE,
        });

        // additional attributes for EC private keys
        templateManager.addTemplate(O_ANY, CKO_PRIVATE_KEY, CKK_EC,
        new CK_ATTRIBUTE[] {
            SIGN_TRUE,
            DERIVE_TRUE,
        });
        // additional attributes for EC public keys
        templateManager.addTemplate(O_ANY, CKO_PUBLIC_KEY, CKK_EC,
        new CK_ATTRIBUTE[] {
            VERIFY_TRUE,
        });
    }

    private final static CK_ATTRIBUTE[] CK_A0 = new CK_ATTRIBUTE[0];

    private String parseOperation() throws IOException {
        String op = parseWord();
        if (op.equals("*")) {
            return TemplateManager.O_ANY;
        } else if (op.equals("generate")) {
            return TemplateManager.O_GENERATE;
        } else if (op.equals("import")) {
            return TemplateManager.O_IMPORT;
        } else {
            throw excLine("Unknown operation " + op);
        }
    }

    private long parseObjectClass() throws IOException {
        String name = parseWord();
        try {
            return Functions.getObjectClassId(name);
        } catch (IllegalArgumentException e) {
            throw excLine("Unknown object class " + name);
        }
    }

    private long parseKeyAlgorithm() throws IOException {
        String name = parseWord();
        if (isNumber(name)) {
            return decodeNumber(name);
        } else {
            try {
                return Functions.getKeyId(name);
            } catch (IllegalArgumentException e) {
                throw excLine("Unknown key algorithm " + name);
            }
        }
    }

    private long decodeAttributeName(String name) throws IOException {
        if (isNumber(name)) {
            return decodeNumber(name);
        } else {
            try {
                return Functions.getAttributeId(name);
            } catch (IllegalArgumentException e) {
                throw excLine("Unknown attribute name " + name);
            }
        }
    }

    private CK_ATTRIBUTE decodeAttributeValue(long id, String value)
            throws IOException {
        if (value.equals("null")) {
            return new CK_ATTRIBUTE(id);
        } else if (value.equals("true")) {
            return new CK_ATTRIBUTE(id, true);
        } else if (value.equals("false")) {
            return new CK_ATTRIBUTE(id, false);
        } else if (isByteArray(value)) {
            return new CK_ATTRIBUTE(id, decodeByteArray(value));
        } else if (isNumber(value)) {
            return new CK_ATTRIBUTE(id, Integer.valueOf(decodeNumber(value)));
        } else {
            throw excLine("Unknown attribute value " + value);
        }
    }

    private void parseNSSArgs(String keyword) throws IOException {
        checkDup(keyword);
        parseEquals();
        int token = nextToken();
        if (token != '"') {
            throw excToken("Expected quoted string");
        }
        nssArgs = expand(st.sval);
        debug("nssArgs: " + nssArgs);
    }

    private void parseHandleStartupErrors(String keyword) throws IOException {
        checkDup(keyword);
        parseEquals();
        String val = parseWord();
        if (val.equals("ignoreAll")) {
            handleStartupErrors = ERR_IGNORE_ALL;
        } else if (val.equals("ignoreMissingLibrary")) {
            handleStartupErrors = ERR_IGNORE_LIB;
        } else if (val.equals("halt")) {
            handleStartupErrors = ERR_HALT;
        } else {
            throw excToken("Invalid value for handleStartupErrors:");
        }
        debug("handleStartupErrors: " + handleStartupErrors);
    }

}

class ConfigurationException extends IOException {
    ConfigurationException(String msg) {
        super(msg);
    }
}
