1 package org.bouncycastle.asn1.x509;
6 import org.bouncycastle.asn1.*;
9 implements DEREncodable
12 * country code - StringType(SIZE(2))
14 public static final DERObjectIdentifier C = new DERObjectIdentifier("2.5.4.6");
17 * organization - StringType(SIZE(1..64))
19 public static final DERObjectIdentifier O = new DERObjectIdentifier("2.5.4.10");
22 * organizational unit name - StringType(SIZE(1..64))
24 public static final DERObjectIdentifier OU = new DERObjectIdentifier("2.5.4.11");
29 public static final DERObjectIdentifier T = new DERObjectIdentifier("2.5.4.12");
32 * common name - StringType(SIZE(1..64))
34 public static final DERObjectIdentifier CN = new DERObjectIdentifier("2.5.4.3");
37 * device serial number name - StringType(SIZE(1..64))
39 public static final DERObjectIdentifier SN = new DERObjectIdentifier("2.5.4.5");
42 * locality name - StringType(SIZE(1..64))
44 public static final DERObjectIdentifier L = new DERObjectIdentifier("2.5.4.7");
47 * state, or province name - StringType(SIZE(1..64))
49 public static final DERObjectIdentifier ST = new DERObjectIdentifier("2.5.4.8");
53 * email address (RSA PKCS#9 extension) - IA5String
55 * note: if you're trying to be ultra orthodox, don't use this! It shouldn't be in here.
57 public static final DERObjectIdentifier EmailAddress = new DERObjectIdentifier("1.2.840.113549.1.9.1");
60 * email address in Verisign certificates
62 public static final DERObjectIdentifier E = EmailAddress;
67 public static final DERObjectIdentifier DC = new DERObjectIdentifier("0.9.2342.19200300.100.1.25");
72 public static final DERObjectIdentifier UID = new DERObjectIdentifier("0.9.2342.19200300.100.1.1");
75 * look up table translating OID values into their common symbols.
77 public static Hashtable OIDLookUp = new Hashtable();
80 * look up table translating common symbols into their OIDS.
82 public static Hashtable SymbolLookUp = new Hashtable();
86 OIDLookUp.put(C, "C");
87 OIDLookUp.put(O, "O");
88 OIDLookUp.put(T, "T");
89 OIDLookUp.put(OU, "OU");
90 OIDLookUp.put(CN, "CN");
91 OIDLookUp.put(L, "L");
92 OIDLookUp.put(ST, "ST");
93 OIDLookUp.put(SN, "SN");
94 OIDLookUp.put(EmailAddress, "E");
95 OIDLookUp.put(DC, "DC");
96 OIDLookUp.put(UID, "UID");
98 SymbolLookUp.put("c", C);
99 SymbolLookUp.put("o", O);
100 SymbolLookUp.put("t", T);
101 SymbolLookUp.put("ou", OU);
102 SymbolLookUp.put("cn", CN);
103 SymbolLookUp.put("l", L);
104 SymbolLookUp.put("st", ST);
105 SymbolLookUp.put("sn", SN);
106 SymbolLookUp.put("emailaddress", E);
107 SymbolLookUp.put("dc", DC);
108 SymbolLookUp.put("e", E);
109 SymbolLookUp.put("uid", UID);
112 private Vector ordering = new Vector();
113 private Vector values = new Vector();
114 private ASN1Sequence seq;
116 public static X509Name getInstance(
117 ASN1TaggedObject obj,
120 return getInstance(ASN1Sequence.getInstance(obj, explicit));
123 public static X509Name getInstance(
126 if (obj == null || obj instanceof X509Name)
128 return (X509Name)obj;
130 else if (obj instanceof ASN1Sequence)
132 return new X509Name((ASN1Sequence)obj);
135 throw new IllegalArgumentException("unknown object in factory");
139 * Constructor from ASN1Sequence
141 * the principal will be a list of constructed sets, each containing an (OID, String) pair.
148 Enumeration e = seq.getObjects();
150 while (e.hasMoreElements())
152 ASN1Set set = (ASN1Set)e.nextElement();
153 ASN1Sequence s = (ASN1Sequence)set.getObjectAt(0);
155 ordering.addElement(s.getObjectAt(0));
156 values.addElement(((DERString)s.getObjectAt(1)).getString());
161 * constructor from a table of attributes.
163 * it's is assumed the table contains OID/String pairs, and the contents
164 * of the table are copied into an internal table as part of the
165 * construction process.
167 * <b>Note:</b> if the name you are trying to generate should be
168 * following a specific ordering, you should use the constructor
169 * with the ordering specified below.
172 Hashtable attributes)
174 this(null, attributes);
178 * constructor from a table of attributes with ordering.
180 * it's is assumed the table contains OID/String pairs, and the contents
181 * of the table are copied into an internal table as part of the
182 * construction process. The ordering vector should contain the OIDs
183 * in the order they are meant to be encoded or printed in toString.
187 Hashtable attributes)
189 if (ordering != null)
191 for (int i = 0; i != ordering.size(); i++)
193 this.ordering.addElement(ordering.elementAt(i));
198 Enumeration e = attributes.keys();
200 while (e.hasMoreElements())
202 this.ordering.addElement(e.nextElement());
206 for (int i = 0; i != this.ordering.size(); i++)
208 DERObjectIdentifier oid = (DERObjectIdentifier)this.ordering.elementAt(i);
210 if (OIDLookUp.get(oid) == null)
212 throw new IllegalArgumentException("Unknown object id - " + oid.getId() + " - passed to distinguished name");
215 if (attributes.get(oid) == null)
217 throw new IllegalArgumentException("No attribute for object id - " + oid.getId() + " - passed to distinguished name");
220 this.values.addElement(attributes.get(oid)); // copy the hash table
225 * takes two vectors one of the oids and the other of the values.
231 if (ordering.size() != values.size())
233 throw new IllegalArgumentException("ordering vector must be same length as values.");
236 for (int i = 0; i < ordering.size(); i++)
238 this.ordering.addElement(ordering.elementAt(i));
239 this.values.addElement(values.elementAt(i));
244 * takes an X509 dir name as a string of the format "C=AU, ST=Victoria", or
245 * some such, converting it into an ordered set of name attributes.
250 X509NameTokenizer nTok = new X509NameTokenizer(dirName);
252 while (nTok.hasMoreTokens())
254 String token = nTok.nextToken();
255 int index = token.indexOf('=');
259 throw new IllegalArgumentException("badly formated directory string");
262 String name = token.substring(0, index);
263 String value = token.substring(index + 1);
264 DERObjectIdentifier oid = null;
266 if (name.toUpperCase().startsWith("OID."))
268 oid = new DERObjectIdentifier(name.substring(4));
270 else if (name.charAt(0) >= '0' && name.charAt(0) <= '9')
272 oid = new DERObjectIdentifier(name);
276 oid = (DERObjectIdentifier)SymbolLookUp.get(name.toLowerCase());
279 throw new IllegalArgumentException("Unknown object id - " + name + " - passed to distinguished name");
283 this.ordering.addElement(oid);
284 this.values.addElement(value);
289 * return false if we have characters out of the range of a printable
290 * string, true otherwise.
292 private boolean canBePrintable(
295 for (int i = str.length() - 1; i >= 0; i--)
297 if (str.charAt(i) > 0x007f)
306 public DERObject getDERObject()
310 DEREncodableVector vec = new DEREncodableVector();
312 for (int i = 0; i != ordering.size(); i++)
314 DEREncodableVector v = new DEREncodableVector();
315 DERObjectIdentifier oid = (DERObjectIdentifier)ordering.elementAt(i);
319 String str = (String)values.elementAt(i);
321 if (oid.equals(EmailAddress))
323 v.add(new DERIA5String(str));
327 if (canBePrintable(str))
329 v.add(new DERPrintableString(str));
333 v.add(new DERUTF8String(str));
337 vec.add(new DERSet(new DERSequence(v)));
340 seq = new DERSequence(vec);
347 * test for equality - note: case is ignored.
349 public boolean equals(Object _obj)
356 if (_obj == null || !(_obj instanceof X509Name))
361 X509Name _oxn = (X509Name)_obj;
362 int _orderingSize = ordering.size();
364 if (_orderingSize != _oxn.ordering.size())
369 boolean[] _indexes = new boolean[_orderingSize];
371 for(int i = 0; i < _orderingSize; i++)
373 boolean _found = false;
374 String _oid = ((DERObjectIdentifier)ordering.elementAt(i)).getId();
375 String _val = (String)values.elementAt(i);
377 for(int j = 0; j < _orderingSize; j++)
379 if(_indexes[j] == true)
384 String _oOID = ((DERObjectIdentifier)_oxn.ordering.elementAt(j)).getId();
385 String _oVal = (String)_oxn.values.elementAt(j);
387 // was equalsIgnoreCase but MIDP doesn't like that.
388 if(_oid.equals(_oOID) && _val.toLowerCase().equals(_oVal.toLowerCase()))
406 public int hashCode()
408 ASN1Sequence seq = (ASN1Sequence)this.getDERObject();
409 Enumeration e = seq.getObjects();
412 while (e.hasMoreElements())
414 hashCode ^= e.nextElement().hashCode();
420 public String toString()
422 StringBuffer buf = new StringBuffer();
423 boolean first = true;
424 Enumeration e1 = ordering.elements();
425 Enumeration e2 = values.elements();
427 while (e1.hasMoreElements())
429 Object oid = e1.nextElement();
430 String sym = (String)OIDLookUp.get(oid);
447 buf.append(((DERObjectIdentifier)oid).getId());
452 int index = buf.length();
454 buf.append((String)e2.nextElement());
456 int end = buf.length();
460 if ((buf.charAt(index) == ',')
461 || (buf.charAt(index) == '"')
462 || (buf.charAt(index) == '\\')
463 || (buf.charAt(index) == '+')
464 || (buf.charAt(index) == '<')
465 || (buf.charAt(index) == '>')
466 || (buf.charAt(index) == ';'))
468 buf.insert(index, "\\");
477 return buf.toString();