1 package org.bouncycastle.asn1.x509;
2
3 import java.io.*;
4 import java.util.*;
5
6 import org.bouncycastle.asn1.*;
7
8 public class X509Name
9 implements DEREncodable
10 {
11
14 public static final DERObjectIdentifier C = new DERObjectIdentifier("2.5.4.6");
15
16
19 public static final DERObjectIdentifier O = new DERObjectIdentifier("2.5.4.10");
20
21
24 public static final DERObjectIdentifier OU = new DERObjectIdentifier("2.5.4.11");
25
26
29 public static final DERObjectIdentifier T = new DERObjectIdentifier("2.5.4.12");
30
31
34 public static final DERObjectIdentifier CN = new DERObjectIdentifier("2.5.4.3");
35
36
39 public static final DERObjectIdentifier SN = new DERObjectIdentifier("2.5.4.5");
40
41
44 public static final DERObjectIdentifier L = new DERObjectIdentifier("2.5.4.7");
45
46
49 public static final DERObjectIdentifier ST = new DERObjectIdentifier("2.5.4.8");
50
51
52
57 public static final DERObjectIdentifier EmailAddress = new DERObjectIdentifier("1.2.840.113549.1.9.1");
58
59
62 public static final DERObjectIdentifier E = EmailAddress;
63
64
67 public static final DERObjectIdentifier DC = new DERObjectIdentifier("0.9.2342.19200300.100.1.25");
68
69
72 public static final DERObjectIdentifier UID = new DERObjectIdentifier("0.9.2342.19200300.100.1.1");
73
74
77 public static Hashtable OIDLookUp = new Hashtable();
78
79
82 public static Hashtable SymbolLookUp = new Hashtable();
83
84 static
85 {
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");
97
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);
110 }
111
112 private Vector ordering = new Vector();
113 private Vector values = new Vector();
114 private ASN1Sequence seq;
115
116 public static X509Name getInstance(
117 ASN1TaggedObject obj,
118 boolean explicit)
119 {
120 return getInstance(ASN1Sequence.getInstance(obj, explicit));
121 }
122
123 public static X509Name getInstance(
124 Object obj)
125 {
126 if (obj == null || obj instanceof X509Name)
127 {
128 return (X509Name)obj;
129 }
130 else if (obj instanceof ASN1Sequence)
131 {
132 return new X509Name((ASN1Sequence)obj);
133 }
134
135 throw new IllegalArgumentException("unknown object in factory");
136 }
137
138
143 public X509Name(
144 ASN1Sequence seq)
145 {
146 this.seq = seq;
147
148 Enumeration e = seq.getObjects();
149
150 while (e.hasMoreElements())
151 {
152 ASN1Set set = (ASN1Set)e.nextElement();
153 ASN1Sequence s = (ASN1Sequence)set.getObjectAt(0);
154
155 ordering.addElement(s.getObjectAt(0));
156 values.addElement(((DERString)s.getObjectAt(1)).getString());
157 }
158 }
159
160
171 public X509Name(
172 Hashtable attributes)
173 {
174 this(null, attributes);
175 }
176
177
185 public X509Name(
186 Vector ordering,
187 Hashtable attributes)
188 {
189 if (ordering != null)
190 {
191 for (int i = 0; i != ordering.size(); i++)
192 {
193 this.ordering.addElement(ordering.elementAt(i));
194 }
195 }
196 else
197 {
198 Enumeration e = attributes.keys();
199
200 while (e.hasMoreElements())
201 {
202 this.ordering.addElement(e.nextElement());
203 }
204 }
205
206 for (int i = 0; i != this.ordering.size(); i++)
207 {
208 DERObjectIdentifier oid = (DERObjectIdentifier)this.ordering.elementAt(i);
209
210 if (OIDLookUp.get(oid) == null)
211 {
212 throw new IllegalArgumentException("Unknown object id - " + oid.getId() + " - passed to distinguished name");
213 }
214
215 if (attributes.get(oid) == null)
216 {
217 throw new IllegalArgumentException("No attribute for object id - " + oid.getId() + " - passed to distinguished name");
218 }
219
220 this.values.addElement(attributes.get(oid));
221 }
222 }
223
224
227 public X509Name(
228 Vector ordering,
229 Vector values)
230 {
231 if (ordering.size() != values.size())
232 {
233 throw new IllegalArgumentException("ordering vector must be same length as values.");
234 }
235
236 for (int i = 0; i < ordering.size(); i++)
237 {
238 this.ordering.addElement(ordering.elementAt(i));
239 this.values.addElement(values.elementAt(i));
240 }
241 }
242
243
247 public X509Name(
248 String dirName)
249 {
250 X509NameTokenizer nTok = new X509NameTokenizer(dirName);
251
252 while (nTok.hasMoreTokens())
253 {
254 String token = nTok.nextToken();
255 int index = token.indexOf('=');
256
257 if (index == -1)
258 {
259 throw new IllegalArgumentException("badly formated directory string");
260 }
261
262 String name = token.substring(0, index);
263 String value = token.substring(index + 1);
264 DERObjectIdentifier oid = null;
265
266 if (name.toUpperCase().startsWith("OID."))
267 {
268 oid = new DERObjectIdentifier(name.substring(4));
269 }
270 else if (name.charAt(0) >= '0' && name.charAt(0) <= '9')
271 {
272 oid = new DERObjectIdentifier(name);
273 }
274 else
275 {
276 oid = (DERObjectIdentifier)SymbolLookUp.get(name.toLowerCase());
277 if (oid == null)
278 {
279 throw new IllegalArgumentException("Unknown object id - " + name + " - passed to distinguished name");
280 }
281 }
282
283 this.ordering.addElement(oid);
284 this.values.addElement(value);
285 }
286 }
287
288
292 private boolean canBePrintable(
293 String str)
294 {
295 for (int i = str.length() - 1; i >= 0; i--)
296 {
297 if (str.charAt(i) > 0x007f)
298 {
299 return false;
300 }
301 }
302
303 return true;
304 }
305
306 public DERObject getDERObject()
307 {
308 if (seq == null)
309 {
310 DEREncodableVector vec = new DEREncodableVector();
311
312 for (int i = 0; i != ordering.size(); i++)
313 {
314 DEREncodableVector v = new DEREncodableVector();
315 DERObjectIdentifier oid = (DERObjectIdentifier)ordering.elementAt(i);
316
317 v.add(oid);
318
319 String str = (String)values.elementAt(i);
320
321 if (oid.equals(EmailAddress))
322 {
323 v.add(new DERIA5String(str));
324 }
325 else
326 {
327 if (canBePrintable(str))
328 {
329 v.add(new DERPrintableString(str));
330 }
331 else
332 {
333 v.add(new DERUTF8String(str));
334 }
335 }
336
337 vec.add(new DERSet(new DERSequence(v)));
338 }
339
340 seq = new DERSequence(vec);
341 }
342
343 return seq;
344 }
345
346
349 public boolean equals(Object _obj)
350 {
351 if (_obj == this)
352 {
353 return true;
354 }
355
356 if (_obj == null || !(_obj instanceof X509Name))
357 {
358 return false;
359 }
360
361 X509Name _oxn = (X509Name)_obj;
362 int _orderingSize = ordering.size();
363
364 if (_orderingSize != _oxn.ordering.size())
365 {
366 return false;
367 }
368
369 boolean[] _indexes = new boolean[_orderingSize];
370
371 for(int i = 0; i < _orderingSize; i++)
372 {
373 boolean _found = false;
374 String _oid = ((DERObjectIdentifier)ordering.elementAt(i)).getId();
375 String _val = (String)values.elementAt(i);
376
377 for(int j = 0; j < _orderingSize; j++)
378 {
379 if(_indexes[j] == true)
380 {
381 continue;
382 }
383
384 String _oOID = ((DERObjectIdentifier)_oxn.ordering.elementAt(j)).getId();
385 String _oVal = (String)_oxn.values.elementAt(j);
386
387
388 if(_oid.equals(_oOID) && _val.toLowerCase().equals(_oVal.toLowerCase()))
389 {
390 _indexes[j] = true;
391 _found = true;
392 break;
393 }
394
395 }
396
397 if(!_found)
398 {
399 return false;
400 }
401 }
402
403 return true;
404 }
405
406 public int hashCode()
407 {
408 ASN1Sequence seq = (ASN1Sequence)this.getDERObject();
409 Enumeration e = seq.getObjects();
410 int hashCode = 0;
411
412 while (e.hasMoreElements())
413 {
414 hashCode ^= e.nextElement().hashCode();
415 }
416
417 return hashCode;
418 }
419
420 public String toString()
421 {
422 StringBuffer buf = new StringBuffer();
423 boolean first = true;
424 Enumeration e1 = ordering.elements();
425 Enumeration e2 = values.elements();
426
427 while (e1.hasMoreElements())
428 {
429 Object oid = e1.nextElement();
430 String sym = (String)OIDLookUp.get(oid);
431
432 if (first)
433 {
434 first = false;
435 }
436 else
437 {
438 buf.append(",");
439 }
440
441 if (sym != null)
442 {
443 buf.append(sym);
444 }
445 else
446 {
447 buf.append(((DERObjectIdentifier)oid).getId());
448 }
449
450 buf.append("=");
451
452 int index = buf.length();
453
454 buf.append((String)e2.nextElement());
455
456 int end = buf.length();
457
458 while (index != end)
459 {
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) == ';'))
467 {
468 buf.insert(index, "\\");
469 index++;
470 end++;
471 }
472
473 index++;
474 }
475 }
476
477 return buf.toString();
478 }
479 }
480