001: /*
002: *
003: *
004: * Copyright 1990-2007 Sun Microsystems, Inc. All Rights Reserved.
005: * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER
006: *
007: * This program is free software; you can redistribute it and/or
008: * modify it under the terms of the GNU General Public License version
009: * 2 only, as published by the Free Software Foundation.
010: *
011: * This program is distributed in the hope that it will be useful, but
012: * WITHOUT ANY WARRANTY; without even the implied warranty of
013: * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
014: * General Public License version 2 for more details (a copy is
015: * included at /legal/license.txt).
016: *
017: * You should have received a copy of the GNU General Public License
018: * version 2 along with this work; if not, write to the Free Software
019: * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA
020: * 02110-1301 USA
021: *
022: * Please contact Sun Microsystems, Inc., 4150 Network Circle, Santa
023: * Clara, CA 95054 or visit www.sun.com if you need additional
024: * information or have any questions.
025: */
026:
027: package acl_data;
028:
029: import java.util.Vector;
030: import java.io.IOException;
031:
032: /**
033: * This class represents Access Control Entry.
034: */
035: public class ACEntry {
036: /** ASN context specific constructed explicit flag used in types (0xA0). */
037: public static final int CONTEXT_CONSTRUCTED_0 = TLV.CONTEXT
038: + TLV.CONSTRUCTED;
039: /** ASN context specific constructed explicit flag used in types (0xA1). */
040: public static final int CONTEXT_CONSTRUCTED_1 = CONTEXT_CONSTRUCTED_0 + 1;
041: /** ASN context specific constructed explicit flag used in types (0xA2). */
042: public static final int CONTEXT_CONSTRUCTED_2 = CONTEXT_CONSTRUCTED_0 + 2;
043: /** ASN context specific constructed explicit flag used in types (0xA3). */
044: public static final int CONTEXT_CONSTRUCTED_3 = CONTEXT_CONSTRUCTED_0 + 3;
045: /** ASN context specific constructed explicit flag used in types (0xA4). */
046: public static final int CONTEXT_CONSTRUCTED_4 = CONTEXT_CONSTRUCTED_0 + 4;
047: /** ASN context specific constructed explicit flag used in types (0xA5). */
048: public static final int CONTEXT_CONSTRUCTED_5 = CONTEXT_CONSTRUCTED_0 + 5;
049: /** ASN context specific constructed explicit flag used in types (0xA6). */
050: public static final int CONTEXT_CONSTRUCTED_6 = CONTEXT_CONSTRUCTED_0 + 6;
051: /** ASN context specific constructed explicit flag used in types (0xA7). */
052: public static final int CONTEXT_CONSTRUCTED_7 = CONTEXT_CONSTRUCTED_0 + 7;
053: /** ASN context specific constructed explicit flag used in types (0xA8). */
054: public static final int CONTEXT_CONSTRUCTED_8 = CONTEXT_CONSTRUCTED_0 + 8;
055:
056: /** ASN context specific primitive explicit flag used in types (0x80). */
057: public static final int CONTEXT_PRIMITIVE_0 = TLV.CONTEXT;
058: /** ASN context specific primitive explicit flag used in types (0x81). */
059: public static final int CONTEXT_PRIMITIVE_1 = CONTEXT_PRIMITIVE_0 + 1;
060: /** ASN context specific primitive explicit flag used in types (0x82). */
061: public static final int CONTEXT_PRIMITIVE_2 = CONTEXT_PRIMITIVE_0 + 2;
062: /** ASN context specific primitive explicit flag used in types (0x83). */
063: public static final int CONTEXT_PRIMITIVE_3 = CONTEXT_PRIMITIVE_0 + 3;
064: /** ASN context specific primitive explicit flag used in types (0x84). */
065: public static final int CONTEXT_PRIMITIVE_4 = CONTEXT_PRIMITIVE_0 + 4;
066: /** ASN context specific primitive explicit flag used in types (0x85). */
067: public static final int CONTEXT_PRIMITIVE_5 = CONTEXT_PRIMITIVE_0 + 5;
068: /** ASN context specific primitive explicit flag used in types (0x86). */
069: public static final int CONTEXT_PRIMITIVE_6 = CONTEXT_PRIMITIVE_0 + 6;
070: /** ASN context specific primitive explicit flag used in types (0x87). */
071: public static final int CONTEXT_PRIMITIVE_7 = CONTEXT_PRIMITIVE_0 + 7;
072: /** ASN context specific primitive explicit flag used in types (0x88). */
073: public static final int CONTEXT_PRIMITIVE_8 = CONTEXT_PRIMITIVE_0 + 8;
074:
075: /** The list of CA names that correspond to rootId element of ACE. */
076: private String[] roots;
077: /** ACE record */
078: private TLV aceRec = null;
079:
080: /**
081: * Constructs ACE.
082: * @param r reader for permissions file.
083: * @param pin_info vector for PIN information.
084: * @throws IOException if I/O error occurs.
085: */
086: ACEntry(ACLFileReader r, Vector pin_info) throws IOException {
087:
088: Vector t_roots = new Vector();
089: Vector t_apdu = new Vector();
090: Vector t_jcrmi = new Vector();
091:
092: r.checkWord("{");
093:
094: TLV perm = new TLV(CONTEXT_CONSTRUCTED_1); /* the Permissions */
095: perm.setChild(new TLV(TLV.NULL_TYPE));
096: TLV tr = perm.child;
097: TLV pin = new TLV(CONTEXT_CONSTRUCTED_2); /* the UserAuthentications */
098: pin.setChild(new TLV(TLV.NULL_TYPE));
099: TLV tp = pin.child;
100: while (true) {
101:
102: String s = r.readWord();
103:
104: if (s.equals("}")) {
105: break;
106: }
107:
108: if (s.equals("root")) {
109: t_roots.addElement(r.readLine());
110: continue;
111: }
112:
113: if (s.equals("apdu")) {
114: readAPDUPermission(r, t_apdu, tr);
115: tr = tr.next;
116: continue;
117: }
118:
119: if (s.equals("jcrmi")) {
120: readJCRMIPermission(r, t_jcrmi, tr);
121: tr = tr.next;
122: continue;
123: }
124:
125: if (s.equals("pin_apdu")) {
126: readAPDUPIN(r, pin_info, tp.setNext(TLV
127: .createSequence()));
128: tp = tp.next;
129: continue;
130: }
131:
132: if (s.equals("pin_jcrmi")) {
133: readJCRMIPIN(r, pin_info, tp.setNext(TLV
134: .createSequence()));
135: tp = tp.next;
136: continue;
137: }
138:
139: throw new IOException();
140: }
141: aceRec = TLV.createSequence(); /* ACE content */
142: if (!t_roots.isEmpty()) {
143: TLV t;
144: roots = new String[t_roots.size()];
145: t = new TLV(CONTEXT_CONSTRUCTED_0); /* the Principals */
146: t.setChild(new TLV(TLV.NULL_TYPE));
147: for (int i = 0; i < t_roots.size(); i++) {
148: roots[i] = (String) t_roots.elementAt(i);
149: createACERoot(t.child.child, roots[i]);
150: }
151: t.child = t.child.next;
152: aceRec.setChild(t);
153: }
154:
155: if ((!t_apdu.isEmpty()) || (!t_jcrmi.isEmpty())) {
156: perm.child = perm.child.next;
157: if (aceRec.child != null) {
158: aceRec.child.setNext(perm);
159: } else {
160: aceRec.setChild(perm);
161: }
162: }
163: if (!pin_info.isEmpty()) {
164: pin.child = pin.child.next;
165: if (aceRec.child != null) {
166: aceRec.child.setNext(pin);
167: } else {
168: aceRec.setChild(pin);
169: }
170: }
171:
172: if (aceRec != null) {
173: aceRec.getValue();
174: }
175:
176: }
177:
178: /**
179: * SEQUENCE OF { sequence of ACE
180: * SEQUENCE { ACE contents
181: * CONTEXT_CONSTRUCTED_0 { the Principals (opt)
182: * SEQUENCE OF { Principal contents
183: * CONTEXT_CONSTRUCTED_0 rootID
184: * OCTET_STRING
185: * CONTEXT_CONSTRUCTED_1 endEntityID
186: * OCTET_STRING
187: * CONTEXT_CONSTRUCTED_2 domain
188: * OBJECT_IDENTIFIER
189: * }
190: * }
191: * CONTEXT_CONSTRUCTED_1 { the Permissions (opt)
192: * SEQUENCE OF { Permissions content
193: * SEQUENCE { Permission content
194: * CONTEXT_CONSTRUCTED_0 { APDUMaskPermission choice
195: * SEQUENCE { APDUPermission
196: * OCTET_STRING (SIZE(4)) APDUHeader
197: * OCTET_STRING (SIZE(4)) APDUMask
198: * }
199: * }
200: * }
201: * CONTEXT_CONSTRUCTED_1 { JCRMIPermission choice
202: * SEQUENCE { JCRMIPermission
203: * SEQUENCE OF { ClassList
204: * UTF8_STRING Class
205: * }
206: * UTF8_STRING hashModifier (opt)
207: * SEQUENCE OF { MethodIDList (opt)
208: * OCTET_STRING (SIZE(4)) MethodID
209: * }
210: * }
211: * }
212: * }
213: * }
214: * }
215: * CONTEXT_CONSTRUCTED_2 { the userAuthentications (opt)
216: * < read user authetications contents >
217: * }
218: * }
219: */
220: /**
221: * Creates ACE root structure
222: * @param t current pointer to TLV.
223: * @param root required root.
224: */
225: private void createACERoot(TLV t, String root) {
226:
227: t.setNext(new TLV(CONTEXT_CONSTRUCTED_0)).setChild(
228: TLV.createOctetString(Utils.stringToBytes(root)));
229: }
230:
231: /**
232: * Returns ACE record
233: * @return TLV
234: */
235: public TLV getACERec() {
236: return aceRec;
237: }
238:
239: /**
240: * Reads APDU permission from file and places it into the vector.
241: * @param r reader for permissions file.
242: * @param t_apdu vector for APDU permissions.
243: * @throws IOException if I/O error occurs.
244: * CONTEXT_CONSTRUCTED_1 { the Permissions (opt)
245: * SEQUENCE OF { Permissions content
246: * CONTEXT_CONSTRUCTED_0 { APDUMaskPermission choice
247: * SEQUENCE { APDUPermission
248: * OCTET_STRING (SIZE(4)) APDUHeader
249: * OCTET_STRING (SIZE(4)) APDUMask
250: * }
251: * }
252: * }
253: */
254: private static void readAPDUPermission(ACLFileReader r,
255: Vector t_apdu, TLV t) throws IOException {
256: TLV ta = t;
257:
258: r.checkWord("{");
259: String s = r.readWord();
260: while (true) {
261:
262: if (s.equals("}")) {
263: break;
264: }
265:
266: byte[] data = new byte[8];
267:
268: for (int i = 0; i < 8; i++) {
269: data[i] = (byte) Short.parseShort(s, 16);
270: s = r.readWord();
271: }
272: t_apdu.addElement(data);
273:
274: ta = ta.setNext(new TLV(CONTEXT_CONSTRUCTED_0));
275: byte[] ah = new byte[4];
276: byte[] am = new byte[4];
277: for (int i = 0; i < 4; i++) {
278: ah[i] = data[i];
279: am[i] = data[i + 4];
280: }
281: ta.setChild(TLV.createOctetString(ah)).setNext(
282: TLV.createOctetString(am));
283: }
284: }
285:
286: /**
287: * Reads JCRMI permission from file and places it into the vector.
288: * @param r reader for permissions file.
289: * @param t_jcrmi vector for JCRMI permissions.
290: * @throws IOException if I/O error occurs.
291: * SEQUENCE OF { ClassList
292: * UTF8_STRING Class
293: * }
294: * UTF8_STRING hashModifier (opt)
295: * SEQUENCE OF { MethodIDList (opt)
296: * OCTET_STRING (SIZE(4)) MethodID
297: * } */
298: private static void readJCRMIPermission(ACLFileReader r,
299: Vector t_jcrmi, TLV t) throws IOException {
300:
301: Vector classes = new Vector();
302: Vector methods = new Vector();
303: String hashModifier = null;
304:
305: r.checkWord("{");
306:
307: TLV tj = new TLV(CONTEXT_CONSTRUCTED_1);
308: t.setNext(tj);
309:
310: TLV c = TLV.createSequence();
311: tj.setChild(c);
312: c = c.setChild(new TLV(TLV.NULL_TYPE));
313: TLV m = null;
314: TLV h = null;
315: while (true) {
316:
317: String s = r.readWord();
318:
319: if (s.equals("}")) {
320: break;
321: }
322:
323: if (s.equals("classes")) {
324: r.checkWord("{");
325: s = r.readWord();
326: while (!s.equals("}")) {
327: classes.addElement(s);
328: c.setNext(TLV.createUTF8String(s));
329: c = c.next;
330: s = r.readWord();
331: }
332: } else if (s.equals("hashModifier")) {
333: hashModifier = r.readWord();
334: h = TLV.createUTF8String(hashModifier);
335: tj.child.setNext(h);
336: } else if (s.equals("methods")) {
337: if (m == null) {
338: m = TLV.createSequence();
339: m.setChild(new TLV(TLV.NULL_TYPE));
340: if (h != null) {
341: h.setNext(m);
342: } else {
343: tj.child.setNext(m);
344: }
345: m = m.child;
346: }
347: r.checkWord("{");
348: s = r.readWord();
349: while (!s.equals("}")) {
350: methods.addElement(s);
351: m.setNext(TLV.createOctetString(getMethodId(
352: hashModifier, s), 0, 4));
353: m = m.next;
354: s = r.readWord();
355: }
356: } else {
357: throw new IOException();
358: }
359: }
360: if (m != null) {
361: if (h != null) {
362: h.next.child = h.next.child.next;
363: } else {
364: tj.child.next.child = tj.child.next.child.next;
365: }
366: }
367:
368: tj.child.child = tj.child.child.next;
369: t_jcrmi.addElement(new JCRMIPermission(hashModifier, classes,
370: methods));
371: }
372:
373: /**
374: * Calculates method ID for given hash modifier and method name.
375: * @param hashModifier hash modifier value.
376: * @param method method name and signature.
377: * @return the identifier.
378: */
379: private static byte[] getMethodId(String hashModifier, String method) {
380:
381: if (hashModifier != null) {
382: method = hashModifier + method;
383: }
384: byte data[] = Utils.stringToBytes(method);
385: data = Utils.getHash(data, 0, data.length);
386: return data;
387: }
388:
389: /**
390: * Reads PIN information from file and adds a new object into vector.
391: * @param r reader for permissions file.
392: * @param dest destination vector.
393: * @param t current pointer to TLV.
394: * @throws IOException if I/O error occurs.
395: */
396: private static void readAPDUPIN(ACLFileReader r, Vector dest, TLV t)
397: throws IOException {
398:
399: r.checkWord("{");
400: r.checkWord("id");
401: int id = r.readByte();
402: Integer[] commands = new Integer[ACLPermissions.CMD_COUNT];
403: t = t.setChild(TLV.createOctetString(new byte[] { (byte) id }))
404: .setNext(new TLV(CONTEXT_CONSTRUCTED_0));
405: TLV ts = t;
406: ts = ts.setChild(new TLV(TLV.NULL_TYPE));
407: while (true) {
408:
409: String s = r.readWord();
410:
411: if (s.equals("}")) {
412: break;
413: }
414:
415: int index = getPINCommandIndex(s);
416:
417: int command = 0;
418: byte[] b = new byte[4];
419: for (int i = 0; i < 4; i++) {
420: b[i] = (byte) r.readByte();
421: command = (command << 8) | b[i];
422: }
423: commands[index] = new Integer(command);
424: ts.setNext(new TLV(0x80 + index, b));
425: ts = ts.next;
426: }
427: t.child = t.child.next;
428: dest.addElement(new PINData(id, commands));
429: }
430:
431: /**
432: * Reads PIN information from file and adds a new object into vector.
433: * @param r reader for permissions file.
434: * @param dest destination vector.
435: * @param t current pointer to TLV.
436: * @throws IOException if I/O error occurs.
437: */
438: private static void readJCRMIPIN(ACLFileReader r, Vector dest, TLV t)
439: throws IOException {
440:
441: r.checkWord("{");
442: r.checkWord("id");
443: int id = r.readByte();
444: String[] commands = new String[ACLPermissions.CMD_COUNT];
445: t = t.setChild(TLV.createOctetString(new byte[] { (byte) id }))
446: .setNext(new TLV(CONTEXT_CONSTRUCTED_1));
447: TLV ts = t;
448: ts = ts.setChild(new TLV(TLV.NULL_TYPE));
449: while (true) {
450:
451: String s = r.readWord();
452: if (s.equals("}")) {
453: break;
454: }
455: int index = getPINCommandIndex(s);
456: commands[index] = r.readWord();
457: ts.setNext(new TLV(0x80 + index, Utils
458: .stringToBytes(commands[index])));
459: ts = ts.next;
460: }
461: t.child = t.child.next;
462: dest.addElement(new PINData(id, commands));
463: }
464:
465: /**
466: * Returns PIN operation identifier for given string.
467: * @param s operation name.
468: * @return PIN operation identifier.
469: * @throws IOException if I/O error occurs.
470: */
471: private static int getPINCommandIndex(String s) throws IOException {
472:
473: if (s.equals("verify")) {
474: return ACLPermissions.CMD_VERIFY;
475: }
476: if (s.equals("change")) {
477: return ACLPermissions.CMD_CHANGE;
478: }
479: if (s.equals("disable")) {
480: return ACLPermissions.CMD_DISABLE;
481: }
482: if (s.equals("enable")) {
483: return ACLPermissions.CMD_ENABLE;
484: }
485: if (s.equals("unblock")) {
486: return ACLPermissions.CMD_UNBLOCK;
487: }
488: throw new IOException("Invalid command: " + s);
489: }
490: }
|