Path: blob/aarch64-shenandoah-jdk8u272-b10/jdk/src/share/classes/sun/security/pkcs11/Config.java
38919 views
/*1* Copyright (c) 2003, 2017, Oracle and/or its affiliates. All rights reserved.2* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.3*4* This code is free software; you can redistribute it and/or modify it5* under the terms of the GNU General Public License version 2 only, as6* published by the Free Software Foundation. Oracle designates this7* particular file as subject to the "Classpath" exception as provided8* by Oracle in the LICENSE file that accompanied this code.9*10* This code is distributed in the hope that it will be useful, but WITHOUT11* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or12* FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License13* version 2 for more details (a copy is included in the LICENSE file that14* accompanied this code).15*16* You should have received a copy of the GNU General Public License version17* 2 along with this work; if not, write to the Free Software Foundation,18* Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.19*20* Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA21* or visit www.oracle.com if you need additional information or have any22* questions.23*/2425package sun.security.pkcs11;2627import java.io.*;28import static java.io.StreamTokenizer.*;29import java.math.BigInteger;30import java.nio.charset.StandardCharsets;31import java.util.*;3233import java.security.*;3435import sun.security.action.GetPropertyAction;36import sun.security.util.PropertyExpander;3738import sun.security.pkcs11.wrapper.*;39import static sun.security.pkcs11.wrapper.PKCS11Constants.*;40import static sun.security.pkcs11.wrapper.CK_ATTRIBUTE.*;4142import static sun.security.pkcs11.TemplateManager.*;4344/**45* Configuration container and file parsing.46*47* @author Andreas Sterbenz48* @since 1.549*/50final class Config {5152static final int ERR_HALT = 1;53static final int ERR_IGNORE_ALL = 2;54static final int ERR_IGNORE_LIB = 3;5556// same as allowSingleThreadedModules but controlled via a system property57// and applied to all providers. if set to false, no SunPKCS11 instances58// will accept single threaded modules regardless of the setting in their59// config files.60private static final boolean staticAllowSingleThreadedModules;6162static {63String p = "sun.security.pkcs11.allowSingleThreadedModules";64String s = AccessController.doPrivileged(new GetPropertyAction(p));65if ("false".equalsIgnoreCase(s)) {66staticAllowSingleThreadedModules = false;67} else {68staticAllowSingleThreadedModules = true;69}70}7172// temporary storage for configurations73// needed because the SunPKCS11 needs to call the superclass constructor74// in provider before accessing any instance variables75private final static Map<String,Config> configMap =76new HashMap<String,Config>();7778static Config getConfig(final String name, final InputStream stream) {79Config config = configMap.get(name);80if (config != null) {81return config;82}83try {84config = new Config(name, stream);85configMap.put(name, config);86return config;87} catch (Exception e) {88throw new ProviderException("Error parsing configuration", e);89}90}9192static Config removeConfig(String name) {93return configMap.remove(name);94}9596private final static boolean DEBUG = false;9798private static void debug(Object o) {99if (DEBUG) {100System.out.println(o);101}102}103104// Reader and StringTokenizer used during parsing105private Reader reader;106107private StreamTokenizer st;108109private Set<String> parsedKeywords;110111// name suffix of the provider112private String name;113114// name of the PKCS#11 library115private String library;116117// description to pass to the provider class118private String description;119120// slotID of the slot to use121private int slotID = -1;122123// slot to use, specified as index in the slotlist124private int slotListIndex = -1;125126// set of enabled mechanisms (or null to use default)127private Set<Long> enabledMechanisms;128129// set of disabled mechanisms130private Set<Long> disabledMechanisms;131132// whether to print debug info during startup133private boolean showInfo = false;134135// template manager, initialized from parsed attributes136private TemplateManager templateManager;137138// how to handle error during startup, one of ERR_139private int handleStartupErrors = ERR_HALT;140141// flag indicating whether the P11KeyStore should142// be more tolerant of input parameters143private boolean keyStoreCompatibilityMode = true;144145// flag indicating whether we need to explicitly cancel operations146// see Token147private boolean explicitCancel = true;148149// how often to test for token insertion, if no token is present150private int insertionCheckInterval = 2000;151152// flag inidicating whether to omit the call to C_Initialize()153// should be used only if we are running within a process that154// has already called it (e.g. Plugin inside of Mozilla/NSS)155private boolean omitInitialize = false;156157// whether to allow modules that only support single threaded access.158// they cannot be used safely from multiple PKCS#11 consumers in the159// same process, for example NSS and SunPKCS11160private boolean allowSingleThreadedModules = true;161162// name of the C function that returns the PKCS#11 functionlist163// This option primarily exists for the deprecated164// Secmod.Module.getProvider() method.165private String functionList = "C_GetFunctionList";166167// whether to use NSS secmod mode. Implicitly set if nssLibraryDirectory,168// nssSecmodDirectory, or nssModule is specified.169private boolean nssUseSecmod;170171// location of the NSS library files (libnss3.so, etc.)172private String nssLibraryDirectory;173174// location of secmod.db175private String nssSecmodDirectory;176177// which NSS module to use178private String nssModule;179180private Secmod.DbMode nssDbMode = Secmod.DbMode.READ_WRITE;181182// Whether the P11KeyStore should specify the CKA_NETSCAPE_DB attribute183// when creating private keys. Only valid if nssUseSecmod is true.184private boolean nssNetscapeDbWorkaround = true;185186// Special init argument string for the NSS softtoken.187// This is used when using the NSS softtoken directly without secmod mode.188private String nssArgs;189190// whether to use NSS trust attributes for the KeyStore of this provider191// this option is for internal use by the SunPKCS11 code only and192// works only for NSS providers created via the Secmod API193private boolean nssUseSecmodTrust = false;194195// Flag to indicate whether the X9.63 encoding for EC points shall be used196// (true) or whether that encoding shall be wrapped in an ASN.1 OctetString197// (false).198private boolean useEcX963Encoding = false;199200// Flag to indicate whether NSS should favour performance (false) or201// memory footprint (true).202private boolean nssOptimizeSpace = false;203204private Config(String filename, InputStream in) throws IOException {205if (in == null) {206if (filename.startsWith("--")) {207// inline config208String config = filename.substring(2).replace("\\n", "\n");209reader = new StringReader(config);210} else {211in = new FileInputStream(expand(filename));212}213}214if (reader == null) {215reader = new BufferedReader(new InputStreamReader(in,216StandardCharsets.ISO_8859_1));217}218parsedKeywords = new HashSet<String>();219st = new StreamTokenizer(reader);220setupTokenizer();221parse();222}223224String getName() {225return name;226}227228String getLibrary() {229return library;230}231232String getDescription() {233if (description != null) {234return description;235}236return "SunPKCS11-" + name + " using library " + library;237}238239int getSlotID() {240return slotID;241}242243int getSlotListIndex() {244if ((slotID == -1) && (slotListIndex == -1)) {245// if neither is set, default to first slot246return 0;247} else {248return slotListIndex;249}250}251252boolean getShowInfo() {253return (SunPKCS11.debug != null) || showInfo;254}255256TemplateManager getTemplateManager() {257if (templateManager == null) {258templateManager = new TemplateManager();259}260return templateManager;261}262263boolean isEnabled(long m) {264if (enabledMechanisms != null) {265return enabledMechanisms.contains(Long.valueOf(m));266}267if (disabledMechanisms != null) {268return !disabledMechanisms.contains(Long.valueOf(m));269}270return true;271}272273int getHandleStartupErrors() {274return handleStartupErrors;275}276277boolean getKeyStoreCompatibilityMode() {278return keyStoreCompatibilityMode;279}280281boolean getExplicitCancel() {282return explicitCancel;283}284285int getInsertionCheckInterval() {286return insertionCheckInterval;287}288289boolean getOmitInitialize() {290return omitInitialize;291}292293boolean getAllowSingleThreadedModules() {294return staticAllowSingleThreadedModules && allowSingleThreadedModules;295}296297String getFunctionList() {298return functionList;299}300301boolean getNssUseSecmod() {302return nssUseSecmod;303}304305String getNssLibraryDirectory() {306return nssLibraryDirectory;307}308309String getNssSecmodDirectory() {310return nssSecmodDirectory;311}312313String getNssModule() {314return nssModule;315}316317Secmod.DbMode getNssDbMode() {318return nssDbMode;319}320321public boolean getNssNetscapeDbWorkaround() {322return nssUseSecmod && nssNetscapeDbWorkaround;323}324325String getNssArgs() {326return nssArgs;327}328329boolean getNssUseSecmodTrust() {330return nssUseSecmodTrust;331}332333boolean getUseEcX963Encoding() {334return useEcX963Encoding;335}336337boolean getNssOptimizeSpace() {338return nssOptimizeSpace;339}340341private static String expand(final String s) throws IOException {342try {343return PropertyExpander.expand(s);344} catch (Exception e) {345throw new RuntimeException(e.getMessage());346}347}348349private void setupTokenizer() {350st.resetSyntax();351st.wordChars('a', 'z');352st.wordChars('A', 'Z');353st.wordChars('0', '9');354st.wordChars(':', ':');355st.wordChars('.', '.');356st.wordChars('_', '_');357st.wordChars('-', '-');358st.wordChars('/', '/');359st.wordChars('\\', '\\');360st.wordChars('$', '$');361st.wordChars('{', '{'); // need {} for property subst362st.wordChars('}', '}');363st.wordChars('*', '*');364st.wordChars('+', '+');365st.wordChars('~', '~');366// XXX check ASCII table and add all other characters except special367368// special: #="(),369st.whitespaceChars(0, ' ');370st.commentChar('#');371st.eolIsSignificant(true);372st.quoteChar('\"');373}374375private ConfigurationException excToken(String msg) {376return new ConfigurationException(msg + " " + st);377}378379private ConfigurationException excLine(String msg) {380return new ConfigurationException(msg + ", line " + st.lineno());381}382383private void parse() throws IOException {384while (true) {385int token = nextToken();386if (token == TT_EOF) {387break;388}389if (token == TT_EOL) {390continue;391}392if (token != TT_WORD) {393throw excToken("Unexpected token:");394}395String word = st.sval;396if (word.equals("name")) {397name = parseStringEntry(word);398} else if (word.equals("library")) {399library = parseLibrary(word);400} else if (word.equals("description")) {401parseDescription(word);402} else if (word.equals("slot")) {403parseSlotID(word);404} else if (word.equals("slotListIndex")) {405parseSlotListIndex(word);406} else if (word.equals("enabledMechanisms")) {407parseEnabledMechanisms(word);408} else if (word.equals("disabledMechanisms")) {409parseDisabledMechanisms(word);410} else if (word.equals("attributes")) {411parseAttributes(word);412} else if (word.equals("handleStartupErrors")) {413parseHandleStartupErrors(word);414} else if (word.endsWith("insertionCheckInterval")) {415insertionCheckInterval = parseIntegerEntry(word);416if (insertionCheckInterval < 100) {417throw excLine(word + " must be at least 100 ms");418}419} else if (word.equals("showInfo")) {420showInfo = parseBooleanEntry(word);421} else if (word.equals("keyStoreCompatibilityMode")) {422keyStoreCompatibilityMode = parseBooleanEntry(word);423} else if (word.equals("explicitCancel")) {424explicitCancel = parseBooleanEntry(word);425} else if (word.equals("omitInitialize")) {426omitInitialize = parseBooleanEntry(word);427} else if (word.equals("allowSingleThreadedModules")) {428allowSingleThreadedModules = parseBooleanEntry(word);429} else if (word.equals("functionList")) {430functionList = parseStringEntry(word);431} else if (word.equals("nssUseSecmod")) {432nssUseSecmod = parseBooleanEntry(word);433} else if (word.equals("nssLibraryDirectory")) {434nssLibraryDirectory = parseLibrary(word);435nssUseSecmod = true;436} else if (word.equals("nssSecmodDirectory")) {437nssSecmodDirectory = expand(parseStringEntry(word));438nssUseSecmod = true;439} else if (word.equals("nssModule")) {440nssModule = parseStringEntry(word);441nssUseSecmod = true;442} else if (word.equals("nssDbMode")) {443String mode = parseStringEntry(word);444if (mode.equals("readWrite")) {445nssDbMode = Secmod.DbMode.READ_WRITE;446} else if (mode.equals("readOnly")) {447nssDbMode = Secmod.DbMode.READ_ONLY;448} else if (mode.equals("noDb")) {449nssDbMode = Secmod.DbMode.NO_DB;450} else {451throw excToken("nssDbMode must be one of readWrite, readOnly, and noDb:");452}453nssUseSecmod = true;454} else if (word.equals("nssNetscapeDbWorkaround")) {455nssNetscapeDbWorkaround = parseBooleanEntry(word);456nssUseSecmod = true;457} else if (word.equals("nssArgs")) {458parseNSSArgs(word);459} else if (word.equals("nssUseSecmodTrust")) {460nssUseSecmodTrust = parseBooleanEntry(word);461} else if (word.equals("useEcX963Encoding")) {462useEcX963Encoding = parseBooleanEntry(word);463} else if (word.equals("nssOptimizeSpace")) {464nssOptimizeSpace = parseBooleanEntry(word);465} else {466throw new ConfigurationException467("Unknown keyword '" + word + "', line " + st.lineno());468}469parsedKeywords.add(word);470}471reader.close();472reader = null;473st = null;474parsedKeywords = null;475if (name == null) {476throw new ConfigurationException("name must be specified");477}478if (nssUseSecmod == false) {479if (library == null) {480throw new ConfigurationException("library must be specified");481}482} else {483if (library != null) {484throw new ConfigurationException485("library must not be specified in NSS mode");486}487if ((slotID != -1) || (slotListIndex != -1)) {488throw new ConfigurationException489("slot and slotListIndex must not be specified in NSS mode");490}491if (nssArgs != null) {492throw new ConfigurationException493("nssArgs must not be specified in NSS mode");494}495if (nssUseSecmodTrust != false) {496throw new ConfigurationException("nssUseSecmodTrust is an "497+ "internal option and must not be specified in NSS mode");498}499}500}501502//503// Parsing helper methods504//505506private int nextToken() throws IOException {507int token = st.nextToken();508debug(st);509return token;510}511512private void parseEquals() throws IOException {513int token = nextToken();514if (token != '=') {515throw excToken("Expected '=', read");516}517}518519private void parseOpenBraces() throws IOException {520while (true) {521int token = nextToken();522if (token == TT_EOL) {523continue;524}525if ((token == TT_WORD) && st.sval.equals("{")) {526return;527}528throw excToken("Expected '{', read");529}530}531532private boolean isCloseBraces(int token) {533return (token == TT_WORD) && st.sval.equals("}");534}535536private String parseWord() throws IOException {537int token = nextToken();538if (token != TT_WORD) {539throw excToken("Unexpected value:");540}541return st.sval;542}543544private String parseStringEntry(String keyword) throws IOException {545checkDup(keyword);546parseEquals();547548int token = nextToken();549if (token != TT_WORD && token != '\"') {550// not a word token nor a string enclosed by double quotes551throw excToken("Unexpected value:");552}553String value = st.sval;554555debug(keyword + ": " + value);556return value;557}558559private boolean parseBooleanEntry(String keyword) throws IOException {560checkDup(keyword);561parseEquals();562boolean value = parseBoolean();563debug(keyword + ": " + value);564return value;565}566567private int parseIntegerEntry(String keyword) throws IOException {568checkDup(keyword);569parseEquals();570int value = decodeNumber(parseWord());571debug(keyword + ": " + value);572return value;573}574575private boolean parseBoolean() throws IOException {576String val = parseWord();577switch (val) {578case "true":579return true;580case "false":581return false;582default:583throw excToken("Expected boolean value, read:");584}585}586587private String parseLine() throws IOException {588// allow quoted string as part of line589String s = null;590while (true) {591int token = nextToken();592if ((token == TT_EOL) || (token == TT_EOF)) {593break;594}595if (token != TT_WORD && token != '\"') {596throw excToken("Unexpected value");597}598if (s == null) {599s = st.sval;600} else {601s = s + " " + st.sval;602}603}604if (s == null) {605throw excToken("Unexpected empty line");606}607return s;608}609610private int decodeNumber(String str) throws IOException {611try {612if (str.startsWith("0x") || str.startsWith("0X")) {613return Integer.parseInt(str.substring(2), 16);614} else {615return Integer.parseInt(str);616}617} catch (NumberFormatException e) {618throw excToken("Expected number, read");619}620}621622private static boolean isNumber(String s) {623if (s.length() == 0) {624return false;625}626char ch = s.charAt(0);627return ((ch >= '0') && (ch <= '9'));628}629630private void parseComma() throws IOException {631int token = nextToken();632if (token != ',') {633throw excToken("Expected ',', read");634}635}636637private static boolean isByteArray(String val) {638return val.startsWith("0h");639}640641private byte[] decodeByteArray(String str) throws IOException {642if (str.startsWith("0h") == false) {643throw excToken("Expected byte array value, read");644}645str = str.substring(2);646// XXX proper hex parsing647try {648return new BigInteger(str, 16).toByteArray();649} catch (NumberFormatException e) {650throw excToken("Expected byte array value, read");651}652}653654private void checkDup(String keyword) throws IOException {655if (parsedKeywords.contains(keyword)) {656throw excLine(keyword + " must only be specified once");657}658}659660//661// individual entry parsing methods662//663664private String parseLibrary(String keyword) throws IOException {665checkDup(keyword);666parseEquals();667String lib = parseLine();668lib = expand(lib);669int i = lib.indexOf("/$ISA/");670if (i != -1) {671// replace "/$ISA/" with "/sparcv9/" on 64-bit Solaris SPARC672// and with "/amd64/" on Solaris AMD64.673// On all other platforms, just turn it into a "/"674String osName = System.getProperty("os.name", "");675String osArch = System.getProperty("os.arch", "");676String prefix = lib.substring(0, i);677String suffix = lib.substring(i + 5);678if (osName.equals("SunOS") && osArch.equals("sparcv9")) {679lib = prefix + "/sparcv9" + suffix;680} else if (osName.equals("SunOS") && osArch.equals("amd64")) {681lib = prefix + "/amd64" + suffix;682} else {683lib = prefix + suffix;684}685}686debug(keyword + ": " + lib);687688// Check to see if full path is specified to prevent the DLL689// preloading attack690if (!(new File(lib)).isAbsolute()) {691throw new ConfigurationException(692"Absolute path required for library value: " + lib);693}694return lib;695}696697private void parseDescription(String keyword) throws IOException {698checkDup(keyword);699parseEquals();700description = parseLine();701debug("description: " + description);702}703704private void parseSlotID(String keyword) throws IOException {705if (slotID >= 0) {706throw excLine("Duplicate slot definition");707}708if (slotListIndex >= 0) {709throw excLine710("Only one of slot and slotListIndex must be specified");711}712parseEquals();713String slotString = parseWord();714slotID = decodeNumber(slotString);715debug("slot: " + slotID);716}717718private void parseSlotListIndex(String keyword) throws IOException {719if (slotListIndex >= 0) {720throw excLine("Duplicate slotListIndex definition");721}722if (slotID >= 0) {723throw excLine724("Only one of slot and slotListIndex must be specified");725}726parseEquals();727String slotString = parseWord();728slotListIndex = decodeNumber(slotString);729debug("slotListIndex: " + slotListIndex);730}731732private void parseEnabledMechanisms(String keyword) throws IOException {733enabledMechanisms = parseMechanisms(keyword);734}735736private void parseDisabledMechanisms(String keyword) throws IOException {737disabledMechanisms = parseMechanisms(keyword);738}739740private Set<Long> parseMechanisms(String keyword) throws IOException {741checkDup(keyword);742Set<Long> mechs = new HashSet<Long>();743parseEquals();744parseOpenBraces();745while (true) {746int token = nextToken();747if (isCloseBraces(token)) {748break;749}750if (token == TT_EOL) {751continue;752}753if (token != TT_WORD) {754throw excToken("Expected mechanism, read");755}756long mech = parseMechanism(st.sval);757mechs.add(Long.valueOf(mech));758}759if (DEBUG) {760System.out.print("mechanisms: [");761for (Long mech : mechs) {762System.out.print(Functions.getMechanismName(mech));763System.out.print(", ");764}765System.out.println("]");766}767return mechs;768}769770private long parseMechanism(String mech) throws IOException {771if (isNumber(mech)) {772return decodeNumber(mech);773} else {774try {775return Functions.getMechanismId(mech);776} catch (IllegalArgumentException e) {777throw excLine("Unknown mechanism: " + mech);778}779}780}781782private void parseAttributes(String keyword) throws IOException {783if (templateManager == null) {784templateManager = new TemplateManager();785}786int token = nextToken();787if (token == '=') {788String s = parseWord();789if (s.equals("compatibility") == false) {790throw excLine("Expected 'compatibility', read " + s);791}792setCompatibilityAttributes();793return;794}795if (token != '(') {796throw excToken("Expected '(' or '=', read");797}798String op = parseOperation();799parseComma();800long objectClass = parseObjectClass();801parseComma();802long keyAlg = parseKeyAlgorithm();803token = nextToken();804if (token != ')') {805throw excToken("Expected ')', read");806}807parseEquals();808parseOpenBraces();809List<CK_ATTRIBUTE> attributes = new ArrayList<CK_ATTRIBUTE>();810while (true) {811token = nextToken();812if (isCloseBraces(token)) {813break;814}815if (token == TT_EOL) {816continue;817}818if (token != TT_WORD) {819throw excToken("Expected mechanism, read");820}821String attributeName = st.sval;822long attributeId = decodeAttributeName(attributeName);823parseEquals();824String attributeValue = parseWord();825attributes.add(decodeAttributeValue(attributeId, attributeValue));826}827templateManager.addTemplate828(op, objectClass, keyAlg, attributes.toArray(CK_A0));829}830831private void setCompatibilityAttributes() {832// all secret keys833templateManager.addTemplate(O_ANY, CKO_SECRET_KEY, PCKK_ANY,834new CK_ATTRIBUTE[] {835TOKEN_FALSE,836SENSITIVE_FALSE,837EXTRACTABLE_TRUE,838ENCRYPT_TRUE,839DECRYPT_TRUE,840WRAP_TRUE,841UNWRAP_TRUE,842});843844// generic secret keys are special845// They are used as MAC keys plus for the SSL/TLS (pre)master secrets846templateManager.addTemplate(O_ANY, CKO_SECRET_KEY, CKK_GENERIC_SECRET,847new CK_ATTRIBUTE[] {848SIGN_TRUE,849VERIFY_TRUE,850ENCRYPT_NULL,851DECRYPT_NULL,852WRAP_NULL,853UNWRAP_NULL,854DERIVE_TRUE,855});856857// all private and public keys858templateManager.addTemplate(O_ANY, CKO_PRIVATE_KEY, PCKK_ANY,859new CK_ATTRIBUTE[] {860TOKEN_FALSE,861SENSITIVE_FALSE,862EXTRACTABLE_TRUE,863});864templateManager.addTemplate(O_ANY, CKO_PUBLIC_KEY, PCKK_ANY,865new CK_ATTRIBUTE[] {866TOKEN_FALSE,867});868869// additional attributes for RSA private keys870templateManager.addTemplate(O_ANY, CKO_PRIVATE_KEY, CKK_RSA,871new CK_ATTRIBUTE[] {872DECRYPT_TRUE,873SIGN_TRUE,874SIGN_RECOVER_TRUE,875UNWRAP_TRUE,876});877// additional attributes for RSA public keys878templateManager.addTemplate(O_ANY, CKO_PUBLIC_KEY, CKK_RSA,879new CK_ATTRIBUTE[] {880ENCRYPT_TRUE,881VERIFY_TRUE,882VERIFY_RECOVER_TRUE,883WRAP_TRUE,884});885886// additional attributes for DSA private keys887templateManager.addTemplate(O_ANY, CKO_PRIVATE_KEY, CKK_DSA,888new CK_ATTRIBUTE[] {889SIGN_TRUE,890});891// additional attributes for DSA public keys892templateManager.addTemplate(O_ANY, CKO_PUBLIC_KEY, CKK_DSA,893new CK_ATTRIBUTE[] {894VERIFY_TRUE,895});896897// additional attributes for DH private keys898templateManager.addTemplate(O_ANY, CKO_PRIVATE_KEY, CKK_DH,899new CK_ATTRIBUTE[] {900DERIVE_TRUE,901});902903// additional attributes for EC private keys904templateManager.addTemplate(O_ANY, CKO_PRIVATE_KEY, CKK_EC,905new CK_ATTRIBUTE[] {906SIGN_TRUE,907DERIVE_TRUE,908});909// additional attributes for EC public keys910templateManager.addTemplate(O_ANY, CKO_PUBLIC_KEY, CKK_EC,911new CK_ATTRIBUTE[] {912VERIFY_TRUE,913});914}915916private final static CK_ATTRIBUTE[] CK_A0 = new CK_ATTRIBUTE[0];917918private String parseOperation() throws IOException {919String op = parseWord();920switch (op) {921case "*":922return TemplateManager.O_ANY;923case "generate":924return TemplateManager.O_GENERATE;925case "import":926return TemplateManager.O_IMPORT;927default:928throw excLine("Unknown operation " + op);929}930}931932private long parseObjectClass() throws IOException {933String name = parseWord();934try {935return Functions.getObjectClassId(name);936} catch (IllegalArgumentException e) {937throw excLine("Unknown object class " + name);938}939}940941private long parseKeyAlgorithm() throws IOException {942String name = parseWord();943if (isNumber(name)) {944return decodeNumber(name);945} else {946try {947return Functions.getKeyId(name);948} catch (IllegalArgumentException e) {949throw excLine("Unknown key algorithm " + name);950}951}952}953954private long decodeAttributeName(String name) throws IOException {955if (isNumber(name)) {956return decodeNumber(name);957} else {958try {959return Functions.getAttributeId(name);960} catch (IllegalArgumentException e) {961throw excLine("Unknown attribute name " + name);962}963}964}965966private CK_ATTRIBUTE decodeAttributeValue(long id, String value)967throws IOException {968if (value.equals("null")) {969return new CK_ATTRIBUTE(id);970} else if (value.equals("true")) {971return new CK_ATTRIBUTE(id, true);972} else if (value.equals("false")) {973return new CK_ATTRIBUTE(id, false);974} else if (isByteArray(value)) {975return new CK_ATTRIBUTE(id, decodeByteArray(value));976} else if (isNumber(value)) {977return new CK_ATTRIBUTE(id, Integer.valueOf(decodeNumber(value)));978} else {979throw excLine("Unknown attribute value " + value);980}981}982983private void parseNSSArgs(String keyword) throws IOException {984checkDup(keyword);985parseEquals();986int token = nextToken();987if (token != '"') {988throw excToken("Expected quoted string");989}990nssArgs = expand(st.sval);991debug("nssArgs: " + nssArgs);992}993994private void parseHandleStartupErrors(String keyword) throws IOException {995checkDup(keyword);996parseEquals();997String val = parseWord();998if (val.equals("ignoreAll")) {999handleStartupErrors = ERR_IGNORE_ALL;1000} else if (val.equals("ignoreMissingLibrary")) {1001handleStartupErrors = ERR_IGNORE_LIB;1002} else if (val.equals("halt")) {1003handleStartupErrors = ERR_HALT;1004} else {1005throw excToken("Invalid value for handleStartupErrors:");1006}1007debug("handleStartupErrors: " + handleStartupErrors);1008}10091010}10111012class ConfigurationException extends IOException {1013private static final long serialVersionUID = 254492758807673194L;1014ConfigurationException(String msg) {1015super(msg);1016}1017}101810191020