001: /*************************************************************************
002: * *
003: * EJBCA: The OpenSource Certificate Authority *
004: * *
005: * This software is free software; you can redistribute it and/or *
006: * modify it under the terms of the GNU Lesser General Public *
007: * License as published by the Free Software Foundation; either *
008: * version 2.1 of the License, or any later version. *
009: * *
010: * See terms of license at gnu.org. *
011: * *
012: *************************************************************************/package org.ejbca.util.dn;
013:
014: import java.util.ArrayList;
015: import java.util.HashMap;
016: import java.util.Iterator;
017:
018: import org.apache.log4j.Logger;
019: import org.ejbca.util.CertTools;
020: import org.ietf.ldap.LDAPDN;
021:
022: /**
023: * A class used to retrieve different fields from a Distiguished Name or Subject Alternate Name
024: * or Subject Directory Attributes strings.
025: *
026: * @author Philip Vendil
027: * @version $Id: DNFieldExtractor.java,v 1.7 2007/01/16 11:46:13 anatom Exp $
028: */
029: public class DNFieldExtractor implements java.io.Serializable {
030: private static final Logger log = Logger
031: .getLogger(DNFieldExtractor.class);
032: // Public constants
033: public static final int TYPE_SUBJECTDN = 0;
034: public static final int TYPE_SUBJECTALTNAME = 1;
035: public static final int TYPE_SUBJECTDIRATTR = 2;
036:
037: // Subject DN Fields.
038: public static final int E = 0;
039: public static final int UID = 1;
040: public static final int CN = 2;
041: public static final int SN = 3;
042: public static final int GIVENNAME = 4;
043: public static final int INITIALS = 5;
044: public static final int SURNAME = 6;
045: public static final int T = 7;
046: public static final int OU = 8;
047: public static final int O = 9;
048: public static final int L = 10;
049: public static final int ST = 11;
050: public static final int DC = 12;
051: public static final int C = 13;
052: public static final int UNSTRUCTUREDADDRESS = 14;
053: public static final int UNSTRUCTUREDNAME = 15;
054:
055: // Subject Alternative Names.
056: public static final int OTHERNAME = 16;
057: public static final int RFC822NAME = 17;
058: public static final int DNSNAME = 18;
059: public static final int IPADDRESS = 19;
060: public static final int X400ADDRESS = 20;
061: public static final int DIRECTORYNAME = 21;
062: public static final int EDIPARTNAME = 22;
063: public static final int URI = 23;
064: public static final int REGISTEREDID = 24;
065: public static final int UPN = 25;
066: public static final int GUID = 26;
067:
068: // Subject Directory Attributes
069: public static final int DATEOFBIRTH = 27;
070: public static final int PLACEOFBIRTH = 28;
071: public static final int GENDER = 29;
072: public static final int COUNTRYOFCITIZENSHIP = 30;
073: public static final int COUNTRYOFRESIDENCE = 31;
074:
075: /**
076: * Creates a new instance of DNFieldExtractor
077: *
078: * @param dn DOCUMENT ME!
079: * @param type DOCUMENT ME!
080: */
081: public DNFieldExtractor(String dn, int type) {
082: dnfields = new HashMap();
083: setDN(dn, type);
084: }
085:
086: /** Fields that can be selected in Certificate profile and Publisher
087: */
088: public static Integer[] getUseFields(int type) {
089: if (type == DNFieldExtractor.TYPE_SUBJECTDN) {
090: return (Integer[]) DnComponents.getDnDnIds().toArray(
091: new Integer[0]);
092: } else if (type == DNFieldExtractor.TYPE_SUBJECTALTNAME) {
093: return (Integer[]) DnComponents.getAltNameDnIds().toArray(
094: new Integer[0]);
095: } else if (type == DNFieldExtractor.TYPE_SUBJECTDIRATTR) {
096: return (Integer[]) DnComponents.getDirAttrDnIds().toArray(
097: new Integer[0]);
098: } else {
099: return new Integer[0];
100: }
101: }
102:
103: public static String getFieldComponent(int field, int type) {
104: if (type == DNFieldExtractor.TYPE_SUBJECTDN) {
105: String ret = DnComponents
106: .getDnExtractorFieldFromDnId(field);
107: return ret;
108: } else if (type == DNFieldExtractor.TYPE_SUBJECTALTNAME) {
109: String ret = DnComponents
110: .getAltNameExtractorFieldFromDnId(field);
111: return ret;
112: } else {
113: String ret = DnComponents
114: .getDirAttrExtractorFieldFromDnId(field);
115: return ret;
116: }
117: }
118:
119: /**
120: * DOCUMENT ME!
121: *
122: * @param dn DOCUMENT ME!
123: * @param type DOCUMENT ME!
124: */
125: public void setDN(String dn, int type) {
126: this .type = type;
127: ArrayList ids;
128: if (type == TYPE_SUBJECTDN) {
129: ids = DnComponents.getDnDnIds();
130: } else if (type == TYPE_SUBJECTALTNAME) {
131: ids = DnComponents.getAltNameDnIds();
132: } else if (type == TYPE_SUBJECTDIRATTR) {
133: ids = DnComponents.getDirAttrDnIds();
134: } else {
135: ids = new ArrayList();
136: }
137: fieldnumbers = new HashMap();
138: Iterator it = ids.iterator();
139: while (it.hasNext()) {
140: Integer id = (Integer) it.next();
141: fieldnumbers.put(id, new Integer(0));
142: }
143:
144: if ((dn != null) && !dn.equalsIgnoreCase("null")) {
145: dnfields = new HashMap();
146:
147: try {
148: String[] dnexploded = LDAPDN.explodeDN(dn, false);
149:
150: for (int i = 0; i < dnexploded.length; i++) {
151: boolean exists = false;
152: Iterator iter = ids.iterator();
153: while (iter.hasNext()) {
154: Integer id = (Integer) iter.next();
155: Integer number = (Integer) fieldnumbers.get(id);
156: String field;
157: if (type == TYPE_SUBJECTDN) {
158: field = DnComponents
159: .getDnExtractorFieldFromDnId(id
160: .intValue());
161: } else if (type == TYPE_SUBJECTALTNAME) {
162: field = DnComponents
163: .getAltNameExtractorFieldFromDnId(id
164: .intValue());
165: } else {
166: field = DnComponents
167: .getDirAttrExtractorFieldFromDnId(id
168: .intValue());
169: }
170: String dnex = dnexploded[i].toUpperCase();
171: if (id.intValue() == DNFieldExtractor.URI) {
172: // Fix up URI, which can have several forms
173: if (dnex.indexOf(CertTools.URI
174: .toUpperCase()
175: + "=") > -1) {
176: field = CertTools.URI.toUpperCase()
177: + "=";
178: }
179: if (dnex.indexOf(CertTools.URI1
180: .toUpperCase()
181: + "=") > -1) {
182: field = CertTools.URI1.toUpperCase()
183: + "=";
184: }
185: }
186: if (dnex.startsWith(field)) {
187: exists = true;
188: String rdn = LDAPDN
189: .unescapeRDN(dnexploded[i]);
190: // We don't want the CN= (or whatever) part of the RDN
191: if (rdn.toUpperCase().startsWith(field)) {
192: rdn = rdn.substring(field.length(), rdn
193: .length());
194: }
195:
196: if (type == TYPE_SUBJECTDN) {
197: dnfields.put(new Integer(
198: (id.intValue() * BOUNDRARY)
199: + number.intValue()),
200: rdn);
201: } else if (type == TYPE_SUBJECTALTNAME) {
202: dnfields.put(new Integer(
203: (id.intValue() * BOUNDRARY)
204: + number.intValue()),
205: rdn);
206: } else if (type == TYPE_SUBJECTDIRATTR) {
207: dnfields.put(new Integer(
208: (id.intValue() * BOUNDRARY)
209: + number.intValue()),
210: rdn);
211: }
212: number = new Integer(number.intValue() + 1);
213: fieldnumbers.put(id, number);
214: }
215: }
216: if (!exists) {
217: existsother = true;
218: }
219: }
220: } catch (Exception e) {
221: log.error("setDN: ", e);
222: illegal = true;
223: if (type == TYPE_SUBJECTDN) {
224: dnfields.put(new Integer((CN * BOUNDRARY)),
225: "Illegal DN : " + dn);
226: } else if (type == TYPE_SUBJECTALTNAME) {
227: dnfields.put(new Integer((RFC822NAME * BOUNDRARY)),
228: "Illegal Subjectaltname : " + dn);
229: } else if (type == TYPE_SUBJECTDIRATTR) {
230: dnfields.put(
231: new Integer((PLACEOFBIRTH * BOUNDRARY)),
232: "Illegal Subjectdirectory attribute : "
233: + dn);
234: }
235: }
236: }
237: }
238:
239: /**
240: * Returns the value of a certain DN component.
241: *
242: * @param field the DN component, one of the constants DNFieldExtractor.CN, ...
243: * @param number the number of the component if several entries for this component exists, normally 0 fir the first
244: *
245: * @return A String for example "PrimeKey" if DNFieldExtractor.O and 0 was passed, "PrimeKey" if DNFieldExtractor.DC and 0 was passed
246: * or "com" if DNFieldExtractor.DC and 1 was passed.
247: * Returns an empty String "", if no such field with the number exists.
248: */
249: public String getField(int field, int number) {
250: String returnval;
251: returnval = (String) dnfields.get(new Integer(
252: (field * BOUNDRARY) + number));
253:
254: if (returnval == null) {
255: returnval = "";
256: }
257:
258: return returnval;
259: }
260:
261: /** Returns a string representation of a certain DN component
262: *
263: * @param field the DN component, one of the constants DNFieldExtractor.CN, ...
264: * @return A String for example "CN=Tomas Gustavsson" if DNFieldExtractor.CN was passed, "DC=PrimeKey,DC=com" if DNFieldExtractor.DC was passed.
265: */
266: public String getFieldString(int field) {
267: String retval = "";
268: String fieldname = DnComponents
269: .getDnExtractorFieldFromDnId(field);
270: if (type != TYPE_SUBJECTDN) {
271: fieldname = DnComponents
272: .getAltNameExtractorFieldFromDnId(field);
273: }
274: int num = getNumberOfFields(field);
275: for (int i = 0; i < num; i++) {
276: if (retval.length() == 0)
277: retval += fieldname + getField(field, i);
278: else
279: retval += "," + fieldname + getField(field, i);
280: }
281: return retval;
282: }
283:
284: /**
285: * Function that returns true if non standard DN field exists in dn string.
286: *
287: * @return true if non standard DN field exists, false otherwise
288: */
289: public boolean existsOther() {
290: return existsother;
291: }
292:
293: /**
294: * Returns the number of one kind of dn field.
295: *
296: * @param field the DN component, one of the constants DNFieldExtractor.CN, ...
297: *
298: * @return number of componenets available for a fiels, for example 1 if DN is "dc=primekey" and 2 if DN is "dc=primekey,dc=com"
299: */
300: public int getNumberOfFields(int field) {
301: Integer ret = (Integer) fieldnumbers.get(new Integer(field));
302: if (ret == null) {
303: log.error("Not finding fieldnumber value for " + field);
304: }
305: return ret.intValue();
306: }
307:
308: /**
309: * Returns the complete array determining the number of DN components of the various types
310: * (i.e. if there are two CNs but 0 Ls etc)
311: *
312: * @return DOCUMENT ME!
313: */
314: public HashMap getNumberOfFields() {
315: return fieldnumbers;
316: }
317:
318: public boolean isIllegal() {
319: return illegal;
320: }
321:
322: private static final int BOUNDRARY = 100;
323: // Mapping dnid to number of occurances in this DN
324: private HashMap fieldnumbers;
325: private HashMap dnfields;
326: private boolean existsother = false;
327: private boolean illegal = false;
328: private int type;
329: }
|