History

My first initial commit with all of mine experimental changes.

Dmitry Kabak (userdima committed 13 years ago

Commit d37b88d1 parent 3f5b46618352 files · +2598093 −-8690Browse files

Showing the changes to java/pkg/sun/security/pkcs11/Config.java (1 of 18352 files). Show all

Unified · Split

java/pkg/sun/security/pkcs11/Config.java+984−0
@@ -0,0 +1,984 @@
1/*
2 * Copyright (c) 2003, 2011, Oracle and/or its affiliates. All rights reserved.
3 * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
4 *
5 * This code is free software; you can redistribute it and/or modify it
6 * under the terms of the GNU General Public License version 2 only, as
7 * published by the Free Software Foundation. Oracle designates this
8 * particular file as subject to the "Classpath" exception as provided
9 * by Oracle in the LICENSE file that accompanied this code.
10 *
11 * This code is distributed in the hope that it will be useful, but WITHOUT
12 * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
13 * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
14 * version 2 for more details (a copy is included in the LICENSE file that
15 * accompanied this code).
16 *
17 * You should have received a copy of the GNU General Public License version
18 * 2 along with this work; if not, write to the Free Software Foundation,
19 * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
20 *
21 * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
22 * or visit www.oracle.com if you need additional information or have any
23 * questions.
24 */
25
26package sun.security.pkcs11;
27
28import java.io.*;
29import static java.io.StreamTokenizer.*;
30import java.math.BigInteger;
31import java.util.*;
32
33import java.security.*;
34
35import sun.security.action.GetPropertyAction;
36import sun.security.util.PropertyExpander;
37
38import sun.security.pkcs11.wrapper.*;
39import static sun.security.pkcs11.wrapper.PKCS11Constants.*;
40import static sun.security.pkcs11.wrapper.CK_ATTRIBUTE.*;
41
42import static sun.security.pkcs11.TemplateManager.*;
43
44/**
45 * Configuration container and file parsing.
46 *
47 * @author Andreas Sterbenz
48 * @since 1.5
49 */
50final class Config {
51
52 static final int ERR_HALT = 1;
53 static final int ERR_IGNORE_ALL = 2;
54 static final int ERR_IGNORE_LIB = 3;
55
56 // same as allowSingleThreadedModules but controlled via a system property
57 // and applied to all providers. if set to false, no SunPKCS11 instances
58 // will accept single threaded modules regardless of the setting in their
59 // config files.
60 private static final boolean staticAllowSingleThreadedModules;
61
62 static {
63 String p = "sun.security.pkcs11.allowSingleThreadedModules";
64 String s = AccessController.doPrivileged(new GetPropertyAction(p));
65 if ("false".equalsIgnoreCase(s)) {
66 staticAllowSingleThreadedModules = false;
67 } else {
68 staticAllowSingleThreadedModules = true;
69 }
70 }
71
72 // temporary storage for configurations
73 // needed because the SunPKCS11 needs to call the superclass constructor
74 // in provider before accessing any instance variables
75 private final static Map<String,Config> configMap =
76 new HashMap<String,Config>();
77
78 static Config getConfig(final String name, final InputStream stream) {
79 Config config = configMap.get(name);
80 if (config != null) {
81 return config;
82 }
83 try {
84 config = new Config(name, stream);
85 configMap.put(name, config);
86 return config;
87 } catch (Exception e) {
88 throw new ProviderException("Error parsing configuration", e);
89 }
90 }
91
92 static Config removeConfig(String name) {
93 return configMap.remove(name);
94 }
95
96 private final static boolean DEBUG = false;
97
98 private static void debug(Object o) {
99 if (DEBUG) {
100 System.out.println(o);
101 }
102 }
103
104 // Reader and StringTokenizer used during parsing
105 private Reader reader;
106
107 private StreamTokenizer st;
108
109 private Set<String> parsedKeywords;
110
111 // name suffix of the provider
112 private String name;
113
114 // name of the PKCS#11 library
115 private String library;
116
117 // description to pass to the provider class
118 private String description;
119
120 // slotID of the slot to use
121 private int slotID = -1;
122
123 // slot to use, specified as index in the slotlist
124 private int slotListIndex = -1;
125
126 // set of enabled mechanisms (or null to use default)
127 private Set<Long> enabledMechanisms;
128
129 // set of disabled mechanisms
130 private Set<Long> disabledMechanisms;
131
132 // whether to print debug info during startup
133 private boolean showInfo = false;
134
135 // template manager, initialized from parsed attributes
136 private TemplateManager templateManager;
137
138 // how to handle error during startup, one of ERR_
139 private int handleStartupErrors = ERR_HALT;
140
141 // flag indicating whether the P11KeyStore should
142 // be more tolerant of input parameters
143 private boolean keyStoreCompatibilityMode = true;
144
145 // flag indicating whether we need to explicitly cancel operations
146 // see Token
147 private boolean explicitCancel = true;
148
149 // how often to test for token insertion, if no token is present
150 private int insertionCheckInterval = 2000;
151
152 // flag inidicating whether to omit the call to C_Initialize()
153 // should be used only if we are running within a process that
154 // has already called it (e.g. Plugin inside of Mozilla/NSS)
155 private boolean omitInitialize = false;
156
157 // whether to allow modules that only support single threaded access.
158 // they cannot be used safely from multiple PKCS#11 consumers in the
159 // same process, for example NSS and SunPKCS11
160 private boolean allowSingleThreadedModules = true;
161
162 // name of the C function that returns the PKCS#11 functionlist
163 // This option primarily exists for the deprecated
164 // Secmod.Module.getProvider() method.
165 private String functionList = "C_GetFunctionList";
166
167 // whether to use NSS secmod mode. Implicitly set if nssLibraryDirectory,
168 // nssSecmodDirectory, or nssModule is specified.
169 private boolean nssUseSecmod;
170
171 // location of the NSS library files (libnss3.so, etc.)
172 private String nssLibraryDirectory;
173
174 // location of secmod.db
175 private String nssSecmodDirectory;
176
177 // which NSS module to use
178 private String nssModule;
179
180 private Secmod.DbMode nssDbMode = Secmod.DbMode.READ_WRITE;
181
182 // Whether the P11KeyStore should specify the CKA_NETSCAPE_DB attribute
183 // when creating private keys. Only valid if nssUseSecmod is true.
184 private boolean nssNetscapeDbWorkaround = true;
185
186 // Special init argument string for the NSS softtoken.
187 // This is used when using the NSS softtoken directly without secmod mode.
188 private String nssArgs;
189
190 // whether to use NSS trust attributes for the KeyStore of this provider
191 // this option is for internal use by the SunPKCS11 code only and
192 // works only for NSS providers created via the Secmod API
193 private boolean nssUseSecmodTrust = false;
194
195 private Config(String filename, InputStream in) throws IOException {
196 if (in == null) {
197 if (filename.startsWith("--")) {
198 // inline config
199 String config = filename.substring(2).replace("\\n", "\n");
200 reader = new StringReader(config);
201 } else {
202 in = new FileInputStream(expand(filename));
203 }
204 }
205 if (reader == null) {
206 reader = new BufferedReader(new InputStreamReader(in));
207 }
208 parsedKeywords = new HashSet<String>();
209 st = new StreamTokenizer(reader);
210 setupTokenizer();
211 parse();
212 }
213
214 String getName() {
215 return name;
216 }
217
218 String getLibrary() {
219 return library;
220 }
221
222 String getDescription() {
223 if (description != null) {
224 return description;
225 }
226 return "SunPKCS11-" + name + " using library " + library;
227 }
228
229 int getSlotID() {
230 return slotID;
231 }
232
233 int getSlotListIndex() {
234 if ((slotID == -1) && (slotListIndex == -1)) {
235 // if neither is set, default to first slot
236 return 0;
237 } else {
238 return slotListIndex;
239 }
240 }
241
242 boolean getShowInfo() {
243 return (SunPKCS11.debug != null) || showInfo;
244 }
245
246 TemplateManager getTemplateManager() {
247 if (templateManager == null) {
248 templateManager = new TemplateManager();
249 }
250 return templateManager;
251 }
252
253 boolean isEnabled(long m) {
254 if (enabledMechanisms != null) {
255 return enabledMechanisms.contains(Long.valueOf(m));
256 }
257 if (disabledMechanisms != null) {
258 return !disabledMechanisms.contains(Long.valueOf(m));
259 }
260 return true;
261 }
262
263 int getHandleStartupErrors() {
264 return handleStartupErrors;
265 }
266
267 boolean getKeyStoreCompatibilityMode() {
268 return keyStoreCompatibilityMode;
269 }
270
271 boolean getExplicitCancel() {
272 return explicitCancel;
273 }
274
275 int getInsertionCheckInterval() {
276 return insertionCheckInterval;
277 }
278
279 boolean getOmitInitialize() {
280 return omitInitialize;
281 }
282
283 boolean getAllowSingleThreadedModules() {
284 return staticAllowSingleThreadedModules && allowSingleThreadedModules;
285 }
286
287 String getFunctionList() {
288 return functionList;
289 }
290
291 boolean getNssUseSecmod() {
292 return nssUseSecmod;
293 }
294
295 String getNssLibraryDirectory() {
296 return nssLibraryDirectory;
297 }
298
299 String getNssSecmodDirectory() {
300 return nssSecmodDirectory;
301 }
302
303 String getNssModule() {
304 return nssModule;
305 }
306
307 Secmod.DbMode getNssDbMode() {
308 return nssDbMode;
309 }
310
311 public boolean getNssNetscapeDbWorkaround() {
312 return nssUseSecmod && nssNetscapeDbWorkaround;
313 }
314
315 String getNssArgs() {
316 return nssArgs;
317 }
318
319 boolean getNssUseSecmodTrust() {
320 return nssUseSecmodTrust;
321 }
322
323 private static String expand(final String s) throws IOException {
324 try {
325 return PropertyExpander.expand(s);
326 } catch (Exception e) {
327 throw new RuntimeException(e.getMessage());
328 }
329 }
330
331 private void setupTokenizer() {
332 st.resetSyntax();
333 st.wordChars('a', 'z');
334 st.wordChars('A', 'Z');
335 st.wordChars('0', '9');
336 st.wordChars(':', ':');
337 st.wordChars('.', '.');
338 st.wordChars('_', '_');
339 st.wordChars('-', '-');
340 st.wordChars('/', '/');
341 st.wordChars('\\', '\\');
342 st.wordChars('$', '$');
343 st.wordChars('{', '{'); // need {} for property subst
344 st.wordChars('}', '}');
345 st.wordChars('*', '*');
346 st.wordChars('+', '+');
347 st.wordChars('~', '~');
348 // XXX check ASCII table and add all other characters except special
349
350 // special: #="(),
351 st.whitespaceChars(0, ' ');
352 st.commentChar('#');
353 st.eolIsSignificant(true);
354 st.quoteChar('\"');
355 }
356
357 private ConfigurationException excToken(String msg) {
358 return new ConfigurationException(msg + " " + st);
359 }
360
361 private ConfigurationException excLine(String msg) {
362 return new ConfigurationException(msg + ", line " + st.lineno());
363 }
364
365 private void parse() throws IOException {
366 while (true) {
367 int token = nextToken();
368 if (token == TT_EOF) {
369 break;
370 }
371 if (token == TT_EOL) {
372 continue;
373 }
374 if (token != TT_WORD) {
375 throw excToken("Unexpected token:");
376 }
377 String word = st.sval;
378 if (word.equals("name")) {
379 name = parseStringEntry(word);
380 } else if (word.equals("library")) {
381 library = parseLibrary(word);
382 } else if (word.equals("description")) {
383 parseDescription(word);
384 } else if (word.equals("slot")) {
385 parseSlotID(word);
386 } else if (word.equals("slotListIndex")) {
387 parseSlotListIndex(word);
388 } else if (word.equals("enabledMechanisms")) {
389 parseEnabledMechanisms(word);
390 } else if (word.equals("disabledMechanisms")) {
391 parseDisabledMechanisms(word);
392 } else if (word.equals("attributes")) {
393 parseAttributes(word);
394 } else if (word.equals("handleStartupErrors")) {
395 parseHandleStartupErrors(word);
396 } else if (word.endsWith("insertionCheckInterval")) {
397 insertionCheckInterval = parseIntegerEntry(word);
398 if (insertionCheckInterval < 100) {
399 throw excLine(word + " must be at least 100 ms");
400 }
401 } else if (word.equals("showInfo")) {
402 showInfo = parseBooleanEntry(word);
403 } else if (word.equals("keyStoreCompatibilityMode")) {
404 keyStoreCompatibilityMode = parseBooleanEntry(word);
405 } else if (word.equals("explicitCancel")) {
406 explicitCancel = parseBooleanEntry(word);
407 } else if (word.equals("omitInitialize")) {
408 omitInitialize = parseBooleanEntry(word);
409 } else if (word.equals("allowSingleThreadedModules")) {
410 allowSingleThreadedModules = parseBooleanEntry(word);
411 } else if (word.equals("functionList")) {
412 functionList = parseStringEntry(word);
413 } else if (word.equals("nssUseSecmod")) {
414 nssUseSecmod = parseBooleanEntry(word);
415 } else if (word.equals("nssLibraryDirectory")) {
416 nssLibraryDirectory = parseLibrary(word);
417 nssUseSecmod = true;
418 } else if (word.equals("nssSecmodDirectory")) {
419 nssSecmodDirectory = expand(parseStringEntry(word));
420 nssUseSecmod = true;
421 } else if (word.equals("nssModule")) {
422 nssModule = parseStringEntry(word);
423 nssUseSecmod = true;
424 } else if (word.equals("nssDbMode")) {
425 String mode = parseStringEntry(word);
426 if (mode.equals("readWrite")) {
427 nssDbMode = Secmod.DbMode.READ_WRITE;
428 } else if (mode.equals("readOnly")) {
429 nssDbMode = Secmod.DbMode.READ_ONLY;
430 } else if (mode.equals("noDb")) {
431 nssDbMode = Secmod.DbMode.NO_DB;
432 } else {
433 throw excToken("nssDbMode must be one of readWrite, readOnly, and noDb:");
434 }
435 nssUseSecmod = true;
436 } else if (word.equals("nssNetscapeDbWorkaround")) {
437 nssNetscapeDbWorkaround = parseBooleanEntry(word);
438 nssUseSecmod = true;
439 } else if (word.equals("nssArgs")) {
440 parseNSSArgs(word);
441 } else if (word.equals("nssUseSecmodTrust")) {
442 nssUseSecmodTrust = parseBooleanEntry(word);
443 } else {
444 throw new ConfigurationException
445 ("Unknown keyword '" + word + "', line " + st.lineno());
446 }
447 parsedKeywords.add(word);
448 }
449 reader.close();
450 reader = null;
451 st = null;
452 parsedKeywords = null;
453 if (name == null) {
454 throw new ConfigurationException("name must be specified");
455 }
456 if (nssUseSecmod == false) {
457 if (library == null) {
458 throw new ConfigurationException("library must be specified");
459 }
460 } else {
461 if (library != null) {
462 throw new ConfigurationException
463 ("library must not be specified in NSS mode");
464 }
465 if ((slotID != -1) || (slotListIndex != -1)) {
466 throw new ConfigurationException
467 ("slot and slotListIndex must not be specified in NSS mode");
468 }
469 if (nssArgs != null) {
470 throw new ConfigurationException
471 ("nssArgs must not be specified in NSS mode");
472 }
473 if (nssUseSecmodTrust != false) {
474 throw new ConfigurationException("nssUseSecmodTrust is an "
475 + "internal option and must not be specified in NSS mode");
476 }
477 }
478 }
479
480 //
481 // Parsing helper methods
482 //
483
484 private int nextToken() throws IOException {
485 int token = st.nextToken();
486 debug(st);
487 return token;
488 }
489
490 private void parseEquals() throws IOException {
491 int token = nextToken();
492 if (token != '=') {
493 throw excToken("Expected '=', read");
494 }
495 }
496
497 private void parseOpenBraces() throws IOException {
498 while (true) {
499 int token = nextToken();
500 if (token == TT_EOL) {
501 continue;
502 }
503 if ((token == TT_WORD) && st.sval.equals("{")) {
504 return;
505 }
506 throw excToken("Expected '{', read");
507 }
508 }
509
510 private boolean isCloseBraces(int token) {
511 return (token == TT_WORD) && st.sval.equals("}");
512 }
513
514 private String parseWord() throws IOException {
515 int token = nextToken();
516 if (token != TT_WORD) {
517 throw excToken("Unexpected value:");
518 }
519 return st.sval;
520 }
521
522 private String parseStringEntry(String keyword) throws IOException {
523 checkDup(keyword);
524 parseEquals();
525
526 int token = nextToken();
527 if (token != TT_WORD && token != '\"') {
528 // not a word token nor a string enclosed by double quotes
529 throw excToken("Unexpected value:");
530 }
531 String value = st.sval;
532
533 debug(keyword + ": " + value);
534 return value;
535 }
536
537 private boolean parseBooleanEntry(String keyword) throws IOException {
538 checkDup(keyword);
539 parseEquals();
540 boolean value = parseBoolean();
541 debug(keyword + ": " + value);
542 return value;
543 }
544
545 private int parseIntegerEntry(String keyword) throws IOException {
546 checkDup(keyword);
547 parseEquals();
548 int value = decodeNumber(parseWord());
549 debug(keyword + ": " + value);
550 return value;
551 }
552
553 private boolean parseBoolean() throws IOException {
554 String val = parseWord();
555 if (val.equals("true")) {
556 return true;
557 } else if (val.equals("false")) {
558 return false;
559 } else {
560 throw excToken("Expected boolean value, read:");
561 }
562 }
563
564 private String parseLine() throws IOException {
565 String s = parseWord();
566 while (true) {
567 int token = nextToken();
568 if ((token == TT_EOL) || (token == TT_EOF)) {
569 break;
570 }
571 if (token != TT_WORD) {
572 throw excToken("Unexpected value");
573 }
574 s = s + " " + st.sval;
575 }
576 return s;
577 }
578
579 private int decodeNumber(String str) throws IOException {
580 try {
581 if (str.startsWith("0x") || str.startsWith("0X")) {
582 return Integer.parseInt(str.substring(2), 16);
583 } else {
584 return Integer.parseInt(str);
585 }
586 } catch (NumberFormatException e) {
587 throw excToken("Expected number, read");
588 }
589 }
590
591 private static boolean isNumber(String s) {
592 if (s.length() == 0) {
593 return false;
594 }
595 char ch = s.charAt(0);
596 return ((ch >= '0') && (ch <= '9'));
597 }
598
599 private void parseComma() throws IOException {
600 int token = nextToken();
601 if (token != ',') {
602 throw excToken("Expected ',', read");
603 }
604 }
605
606 private static boolean isByteArray(String val) {
607 return val.startsWith("0h");
608 }
609
610 private byte[] decodeByteArray(String str) throws IOException {
611 if (str.startsWith("0h") == false) {
612 throw excToken("Expected byte array value, read");
613 }
614 str = str.substring(2);
615 // XXX proper hex parsing
616 try {
617 return new BigInteger(str, 16).toByteArray();
618 } catch (NumberFormatException e) {
619 throw excToken("Expected byte array value, read");
620 }
621 }
622
623 private void checkDup(String keyword) throws IOException {
624 if (parsedKeywords.contains(keyword)) {
625 throw excLine(keyword + " must only be specified once");
626 }
627 }
628
629 //
630 // individual entry parsing methods
631 //
632
633 private String parseLibrary(String keyword) throws IOException {
634 checkDup(keyword);
635 parseEquals();
636 String lib = parseLine();
637 lib = expand(lib);
638 int i = lib.indexOf("/$ISA/");
639 if (i != -1) {
640 // replace "/$ISA/" with "/sparcv9/" on 64-bit Solaris SPARC
641 // and with "/amd64/" on Solaris AMD64.
642 // On all other platforms, just turn it into a "/"
643 String osName = System.getProperty("os.name", "");
644 String osArch = System.getProperty("os.arch", "");
645 String prefix = lib.substring(0, i);
646 String suffix = lib.substring(i + 5);
647 if (osName.equals("SunOS") && osArch.equals("sparcv9")) {
648 lib = prefix + "/sparcv9" + suffix;
649 } else if (osName.equals("SunOS") && osArch.equals("amd64")) {
650 lib = prefix + "/amd64" + suffix;
651 } else {
652 lib = prefix + suffix;
653 }
654 }
655 debug(keyword + ": " + lib);
656
657 // Check to see if full path is specified to prevent the DLL
658 // preloading attack
659 if (!(new File(lib)).isAbsolute()) {
660 throw new ConfigurationException(
661 "Absolute path required for library value: " + lib);
662 }
663 return lib;
664 }
665
666 private void parseDescription(String keyword) throws IOException {
667 checkDup(keyword);
668 parseEquals();
669 description = parseLine();
670 debug("description: " + description);
671 }
672
673 private void parseSlotID(String keyword) throws IOException {
674 if (slotID >= 0) {
675 throw excLine("Duplicate slot definition");
676 }
677 if (slotListIndex >= 0) {
678 throw excLine
679 ("Only one of slot and slotListIndex must be specified");
680 }
681 parseEquals();
682 String slotString = parseWord();
683 slotID = decodeNumber(slotString);
684 debug("slot: " + slotID);
685 }
686
687 private void parseSlotListIndex(String keyword) throws IOException {
688 if (slotListIndex >= 0) {
689 throw excLine("Duplicate slotListIndex definition");
690 }
691 if (slotID >= 0) {
692 throw excLine
693 ("Only one of slot and slotListIndex must be specified");
694 }
695 parseEquals();
696 String slotString = parseWord();
697 slotListIndex = decodeNumber(slotString);
698 debug("slotListIndex: " + slotListIndex);
699 }
700
701 private void parseEnabledMechanisms(String keyword) throws IOException {
702 enabledMechanisms = parseMechanisms(keyword);
703 }
704
705 private void parseDisabledMechanisms(String keyword) throws IOException {
706 disabledMechanisms = parseMechanisms(keyword);
707 }
708
709 private Set<Long> parseMechanisms(String keyword) throws IOException {
710 checkDup(keyword);
711 Set<Long> mechs = new HashSet<Long>();
712 parseEquals();
713 parseOpenBraces();
714 while (true) {
715 int token = nextToken();
716 if (isCloseBraces(token)) {
717 break;
718 }
719 if (token == TT_EOL) {
720 continue;
721 }
722 if (token != TT_WORD) {
723 throw excToken("Expected mechanism, read");
724 }
725 long mech = parseMechanism(st.sval);
726 mechs.add(Long.valueOf(mech));
727 }
728 if (DEBUG) {
729 System.out.print("mechanisms: [");
730 for (Long mech : mechs) {
731 System.out.print(Functions.getMechanismName(mech));
732 System.out.print(", ");
733 }
734 System.out.println("]");
735 }
736 return mechs;
737 }
738
739 private long parseMechanism(String mech) throws IOException {
740 if (isNumber(mech)) {
741 return decodeNumber(mech);
742 } else {
743 try {
744 return Functions.getMechanismId(mech);
745 } catch (IllegalArgumentException e) {
746 throw excLine("Unknown mechanism: " + mech);
747 }
748 }
749 }
750
751 private void parseAttributes(String keyword) throws IOException {
752 if (templateManager == null) {
753 templateManager = new TemplateManager();
754 }
755 int token = nextToken();
756 if (token == '=') {
757 String s = parseWord();
758 if (s.equals("compatibility") == false) {
759 throw excLine("Expected 'compatibility', read " + s);
760 }
761 setCompatibilityAttributes();
762 return;
763 }
764 if (token != '(') {
765 throw excToken("Expected '(' or '=', read");
766 }
767 String op = parseOperation();
768 parseComma();
769 long objectClass = parseObjectClass();
770 parseComma();
771 long keyAlg = parseKeyAlgorithm();
772 token = nextToken();
773 if (token != ')') {
774 throw excToken("Expected ')', read");
775 }
776 parseEquals();
777 parseOpenBraces();
778 List<CK_ATTRIBUTE> attributes = new ArrayList<CK_ATTRIBUTE>();
779 while (true) {
780 token = nextToken();
781 if (isCloseBraces(token)) {
782 break;
783 }
784 if (token == TT_EOL) {
785 continue;
786 }
787 if (token != TT_WORD) {
788 throw excToken("Expected mechanism, read");
789 }
790 String attributeName = st.sval;
791 long attributeId = decodeAttributeName(attributeName);
792 parseEquals();
793 String attributeValue = parseWord();
794 attributes.add(decodeAttributeValue(attributeId, attributeValue));
795 }
796 templateManager.addTemplate
797 (op, objectClass, keyAlg, attributes.toArray(CK_A0));
798 }
799
800 private void setCompatibilityAttributes() {
801 // all secret keys
802 templateManager.addTemplate(O_ANY, CKO_SECRET_KEY, PCKK_ANY,
803 new CK_ATTRIBUTE[] {
804 TOKEN_FALSE,
805 SENSITIVE_FALSE,
806 EXTRACTABLE_TRUE,
807 ENCRYPT_TRUE,
808 DECRYPT_TRUE,
809 WRAP_TRUE,
810 UNWRAP_TRUE,
811 });
812
813 // generic secret keys are special
814 // They are used as MAC keys plus for the SSL/TLS (pre)master secrets
815 templateManager.addTemplate(O_ANY, CKO_SECRET_KEY, CKK_GENERIC_SECRET,
816 new CK_ATTRIBUTE[] {
817 SIGN_TRUE,
818 VERIFY_TRUE,
819 ENCRYPT_NULL,
820 DECRYPT_NULL,
821 WRAP_NULL,
822 UNWRAP_NULL,
823 DERIVE_TRUE,
824 });
825
826 // all private and public keys
827 templateManager.addTemplate(O_ANY, CKO_PRIVATE_KEY, PCKK_ANY,
828 new CK_ATTRIBUTE[] {
829 TOKEN_FALSE,
830 SENSITIVE_FALSE,
831 EXTRACTABLE_TRUE,
832 });
833 templateManager.addTemplate(O_ANY, CKO_PUBLIC_KEY, PCKK_ANY,
834 new CK_ATTRIBUTE[] {
835 TOKEN_FALSE,
836 });
837
838 // additional attributes for RSA private keys
839 templateManager.addTemplate(O_ANY, CKO_PRIVATE_KEY, CKK_RSA,
840 new CK_ATTRIBUTE[] {
841 DECRYPT_TRUE,
842 SIGN_TRUE,
843 SIGN_RECOVER_TRUE,
844 UNWRAP_TRUE,
845 });
846 // additional attributes for RSA public keys
847 templateManager.addTemplate(O_ANY, CKO_PUBLIC_KEY, CKK_RSA,
848 new CK_ATTRIBUTE[] {
849 ENCRYPT_TRUE,
850 VERIFY_TRUE,
851 VERIFY_RECOVER_TRUE,
852 WRAP_TRUE,
853 });
854
855 // additional attributes for DSA private keys
856 templateManager.addTemplate(O_ANY, CKO_PRIVATE_KEY, CKK_DSA,
857 new CK_ATTRIBUTE[] {
858 SIGN_TRUE,
859 });
860 // additional attributes for DSA public keys
861 templateManager.addTemplate(O_ANY, CKO_PUBLIC_KEY, CKK_DSA,
862 new CK_ATTRIBUTE[] {
863 VERIFY_TRUE,
864 });
865
866 // additional attributes for DH private keys
867 templateManager.addTemplate(O_ANY, CKO_PRIVATE_KEY, CKK_DH,
868 new CK_ATTRIBUTE[] {
869 DERIVE_TRUE,
870 });
871
872 // additional attributes for EC private keys
873 templateManager.addTemplate(O_ANY, CKO_PRIVATE_KEY, CKK_EC,
874 new CK_ATTRIBUTE[] {
875 SIGN_TRUE,
876 DERIVE_TRUE,
877 });
878 // additional attributes for EC public keys
879 templateManager.addTemplate(O_ANY, CKO_PUBLIC_KEY, CKK_EC,
880 new CK_ATTRIBUTE[] {
881 VERIFY_TRUE,
882 });
883 }
884
885 private final static CK_ATTRIBUTE[] CK_A0 = new CK_ATTRIBUTE[0];
886
887 private String parseOperation() throws IOException {
888 String op = parseWord();
889 if (op.equals("*")) {
890 return TemplateManager.O_ANY;
891 } else if (op.equals("generate")) {
892 return TemplateManager.O_GENERATE;
893 } else if (op.equals("import")) {
894 return TemplateManager.O_IMPORT;
895 } else {
896 throw excLine("Unknown operation " + op);
897 }
898 }
899
900 private long parseObjectClass() throws IOException {
901 String name = parseWord();
902 try {
903 return Functions.getObjectClassId(name);
904 } catch (IllegalArgumentException e) {
905 throw excLine("Unknown object class " + name);
906 }
907 }
908
909 private long parseKeyAlgorithm() throws IOException {
910 String name = parseWord();
911 if (isNumber(name)) {
912 return decodeNumber(name);
913 } else {
914 try {
915 return Functions.getKeyId(name);
916 } catch (IllegalArgumentException e) {
917 throw excLine("Unknown key algorithm " + name);
918 }
919 }
920 }
921
922 private long decodeAttributeName(String name) throws IOException {
923 if (isNumber(name)) {
924 return decodeNumber(name);
925 } else {
926 try {
927 return Functions.getAttributeId(name);
928 } catch (IllegalArgumentException e) {
929 throw excLine("Unknown attribute name " + name);
930 }
931 }
932 }
933
934 private CK_ATTRIBUTE decodeAttributeValue(long id, String value)
935 throws IOException {
936 if (value.equals("null")) {
937 return new CK_ATTRIBUTE(id);
938 } else if (value.equals("true")) {
939 return new CK_ATTRIBUTE(id, true);
940 } else if (value.equals("false")) {
941 return new CK_ATTRIBUTE(id, false);
942 } else if (isByteArray(value)) {
943 return new CK_ATTRIBUTE(id, decodeByteArray(value));
944 } else if (isNumber(value)) {
945 return new CK_ATTRIBUTE(id, Integer.valueOf(decodeNumber(value)));
946 } else {
947 throw excLine("Unknown attribute value " + value);
948 }
949 }
950
951 private void parseNSSArgs(String keyword) throws IOException {
952 checkDup(keyword);
953 parseEquals();
954 int token = nextToken();
955 if (token != '"') {
956 throw excToken("Expected quoted string");
957 }
958 nssArgs = expand(st.sval);
959 debug("nssArgs: " + nssArgs);
960 }
961
962 private void parseHandleStartupErrors(String keyword) throws IOException {
963 checkDup(keyword);
964 parseEquals();
965 String val = parseWord();
966 if (val.equals("ignoreAll")) {
967 handleStartupErrors = ERR_IGNORE_ALL;
968 } else if (val.equals("ignoreMissingLibrary")) {
969 handleStartupErrors = ERR_IGNORE_LIB;
970 } else if (val.equals("halt")) {
971 handleStartupErrors = ERR_HALT;
972 } else {
973 throw excToken("Invalid value for handleStartupErrors:");
974 }
975 debug("handleStartupErrors: " + handleStartupErrors);
976 }
977
978}
979
980class ConfigurationException extends IOException {
981 ConfigurationException(String msg) {
982 super(msg);
983 }
984}