KickJava   Java API By Example, From Geeks To Geeks.

Java > Open Source Codes > org > apache > geronimo > util > asn1 > x509 > X509Name


1 /**
2  * Licensed to the Apache Software Foundation (ASF) under one or more
3  * contributor license agreements. See the NOTICE file distributed with
4  * this work for additional information regarding copyright ownership.
5  * The ASF licenses this file to You under the Apache License, Version 2.0
6  * (the "License"); you may not use this file except in compliance with
7  * the License. You may obtain a copy of the License at
8  *
9  * http://www.apache.org/licenses/LICENSE-2.0
10  *
11  * Unless required by applicable law or agreed to in writing, software
12  * distributed under the License is distributed on an "AS IS" BASIS,
13  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
14  * See the License for the specific language governing permissions and
15  * limitations under the License.
16  */

17
18 package org.apache.geronimo.util.asn1.x509;
19
20 import java.util.Enumeration JavaDoc;
21 import java.util.Hashtable JavaDoc;
22 import java.util.Vector JavaDoc;
23
24 import org.apache.geronimo.util.asn1.*;
25 import org.apache.geronimo.util.asn1.pkcs.PKCSObjectIdentifiers;
26
27 /**
28  * <pre>
29  * RDNSequence ::= SEQUENCE OF RelativeDistinguishedName
30  *
31  * RelativeDistinguishedName ::= SET SIZE (1..MAX) OF AttributeTypeAndValue
32  *
33  * AttributeTypeAndValue ::= SEQUENCE {
34  * type OBJECT IDENTIFIER,
35  * value ANY }
36  * </pre>
37  */

38 public class X509Name
39     extends ASN1Encodable
40 {
41     /**
42      * country code - StringType(SIZE(2))
43      */

44     public static final DERObjectIdentifier C = new DERObjectIdentifier("2.5.4.6");
45
46     /**
47      * organization - StringType(SIZE(1..64))
48      */

49     public static final DERObjectIdentifier O = new DERObjectIdentifier("2.5.4.10");
50
51     /**
52      * organizational unit name - StringType(SIZE(1..64))
53      */

54     public static final DERObjectIdentifier OU = new DERObjectIdentifier("2.5.4.11");
55
56     /**
57      * Title
58      */

59     public static final DERObjectIdentifier T = new DERObjectIdentifier("2.5.4.12");
60
61     /**
62      * common name - StringType(SIZE(1..64))
63      */

64     public static final DERObjectIdentifier CN = new DERObjectIdentifier("2.5.4.3");
65
66     /**
67      * device serial number name - StringType(SIZE(1..64))
68      */

69     public static final DERObjectIdentifier SN = new DERObjectIdentifier("2.5.4.5");
70
71     /**
72      * locality name - StringType(SIZE(1..64))
73      */

74     public static final DERObjectIdentifier L = new DERObjectIdentifier("2.5.4.7");
75
76     /**
77      * state, or province name - StringType(SIZE(1..64))
78      */

79     public static final DERObjectIdentifier ST = new DERObjectIdentifier("2.5.4.8");
80
81     /**
82      * Naming attributes of type X520name
83      */

84     public static final DERObjectIdentifier SURNAME = new DERObjectIdentifier("2.5.4.4");
85     public static final DERObjectIdentifier GIVENNAME = new DERObjectIdentifier("2.5.4.42");
86     public static final DERObjectIdentifier INITIALS = new DERObjectIdentifier("2.5.4.43");
87     public static final DERObjectIdentifier GENERATION = new DERObjectIdentifier("2.5.4.44");
88     public static final DERObjectIdentifier UNIQUE_IDENTIFIER = new DERObjectIdentifier("2.5.4.45");
89
90     /**
91      * Email address (RSA PKCS#9 extension) - IA5String.
92      * <p>Note: if you're trying to be ultra orthodox, don't use this! It shouldn't be in here.
93      */

94     public static final DERObjectIdentifier EmailAddress = PKCSObjectIdentifiers.pkcs_9_at_emailAddress;
95
96     /**
97      * more from PKCS#9
98      */

99     public static final DERObjectIdentifier UnstructuredName = PKCSObjectIdentifiers.pkcs_9_at_unstructuredName;
100     public static final DERObjectIdentifier UnstructuredAddress = PKCSObjectIdentifiers.pkcs_9_at_unstructuredAddress;
101
102     /**
103      * email address in Verisign certificates
104      */

105     public static final DERObjectIdentifier E = EmailAddress;
106
107     /*
108      * others...
109      */

110     public static final DERObjectIdentifier DC = new DERObjectIdentifier("0.9.2342.19200300.100.1.25");
111
112     /**
113      * LDAP User id.
114      */

115     public static final DERObjectIdentifier UID = new DERObjectIdentifier("0.9.2342.19200300.100.1.1");
116
117     /**
118      * look up table translating OID values into their common symbols - this static is scheduled for deletion
119      */

120     public static Hashtable JavaDoc OIDLookUp = new Hashtable JavaDoc();
121
122     /**
123      * determines whether or not strings should be processed and printed
124      * from back to front.
125      */

126     public static boolean DefaultReverse = false;
127
128     /**
129      * default look up table translating OID values into their common symbols following
130      * the convention in RFC 2253 with a few extras
131      */

132     public static Hashtable JavaDoc DefaultSymbols = OIDLookUp;
133
134     /**
135      * look up table translating OID values into their common symbols following the convention in RFC 2253
136      * with a few extras
137      */

138     public static Hashtable JavaDoc RFC2253Symbols = new Hashtable JavaDoc();
139
140     /**
141      * look up table translating string values into their OIDS -
142      * this static is scheduled for deletion
143      */

144     public static Hashtable JavaDoc SymbolLookUp = new Hashtable JavaDoc();
145
146     /**
147      * look up table translating common symbols into their OIDS.
148      */

149     public static Hashtable JavaDoc DefaultLookUp = SymbolLookUp;
150
151     static
152     {
153         DefaultSymbols.put(C, "C");
154         DefaultSymbols.put(O, "O");
155         DefaultSymbols.put(T, "T");
156         DefaultSymbols.put(OU, "OU");
157         DefaultSymbols.put(CN, "CN");
158         DefaultSymbols.put(L, "L");
159         DefaultSymbols.put(ST, "ST");
160         DefaultSymbols.put(SN, "SN");
161         DefaultSymbols.put(EmailAddress, "E");
162         DefaultSymbols.put(DC, "DC");
163         DefaultSymbols.put(UID, "UID");
164         DefaultSymbols.put(SURNAME, "SURNAME");
165         DefaultSymbols.put(GIVENNAME, "GIVENNAME");
166         DefaultSymbols.put(INITIALS, "INITIALS");
167         DefaultSymbols.put(GENERATION, "GENERATION");
168         DefaultSymbols.put(UnstructuredAddress, "unstructuredAddress");
169         DefaultSymbols.put(UnstructuredName, "unstructuredName");
170
171         RFC2253Symbols.put(C, "C");
172         RFC2253Symbols.put(O, "O");
173         RFC2253Symbols.put(T, "T");
174         RFC2253Symbols.put(OU, "OU");
175         RFC2253Symbols.put(CN, "CN");
176         RFC2253Symbols.put(L, "L");
177         RFC2253Symbols.put(ST, "ST");
178         RFC2253Symbols.put(SN, "SN");
179         RFC2253Symbols.put(EmailAddress, "EMAILADDRESS");
180         RFC2253Symbols.put(DC, "DC");
181         RFC2253Symbols.put(UID, "UID");
182         RFC2253Symbols.put(SURNAME, "SURNAME");
183         RFC2253Symbols.put(GIVENNAME, "GIVENNAME");
184         RFC2253Symbols.put(INITIALS, "INITIALS");
185         RFC2253Symbols.put(GENERATION, "GENERATION");
186
187         DefaultLookUp.put("c", C);
188         DefaultLookUp.put("o", O);
189         DefaultLookUp.put("t", T);
190         DefaultLookUp.put("ou", OU);
191         DefaultLookUp.put("cn", CN);
192         DefaultLookUp.put("l", L);
193         DefaultLookUp.put("st", ST);
194         DefaultLookUp.put("sn", SN);
195         DefaultLookUp.put("emailaddress", E);
196         DefaultLookUp.put("dc", DC);
197         DefaultLookUp.put("e", E);
198         DefaultLookUp.put("uid", UID);
199         DefaultLookUp.put("surname", SURNAME);
200         DefaultLookUp.put("givenname", GIVENNAME);
201         DefaultLookUp.put("initials", INITIALS);
202         DefaultLookUp.put("generation", GENERATION);
203         DefaultLookUp.put("unstructuredaddress", UnstructuredAddress);
204         DefaultLookUp.put("unstructuredname", UnstructuredName);
205     }
206
207     private X509NameEntryConverter converter = null;
208     private Vector JavaDoc ordering = new Vector JavaDoc();
209     private Vector JavaDoc values = new Vector JavaDoc();
210     private Vector JavaDoc added = new Vector JavaDoc();
211
212     private ASN1Sequence seq;
213
214     /**
215      * Return a X509Name based on the passed in tagged object.
216      *
217      * @param obj tag object holding name.
218      * @param explicit true if explicitly tagged false otherwise.
219      * @return the X509Name
220      */

221     public static X509Name getInstance(
222         ASN1TaggedObject obj,
223         boolean explicit)
224     {
225         return getInstance(ASN1Sequence.getInstance(obj, explicit));
226     }
227
228     public static X509Name getInstance(
229         Object JavaDoc obj)
230     {
231         if (obj == null || obj instanceof X509Name)
232         {
233             return (X509Name)obj;
234         }
235         else if (obj instanceof ASN1Sequence)
236         {
237             return new X509Name((ASN1Sequence)obj);
238         }
239
240         throw new IllegalArgumentException JavaDoc("unknown object in factory");
241     }
242
243     /**
244      * Constructor from ASN1Sequence
245      *
246      * the principal will be a list of constructed sets, each containing an (OID, String) pair.
247      */

248     public X509Name(
249         ASN1Sequence seq)
250     {
251         this.seq = seq;
252
253         Enumeration JavaDoc e = seq.getObjects();
254
255         while (e.hasMoreElements())
256         {
257             ASN1Set set = (ASN1Set)e.nextElement();
258
259             for (int i = 0; i < set.size(); i++)
260             {
261                    ASN1Sequence s = (ASN1Sequence)set.getObjectAt(i);
262
263                    ordering.addElement(s.getObjectAt(0));
264                    values.addElement(((DERString) s.getObjectAt(1)).getString());
265                    added.addElement((i != 0) ? new Boolean JavaDoc(true) : new Boolean JavaDoc(false));
266             }
267         }
268     }
269
270     /**
271      * constructor from a table of attributes.
272      * <p>
273      * it's is assumed the table contains OID/String pairs, and the contents
274      * of the table are copied into an internal table as part of the
275      * construction process.
276      * <p>
277      * <b>Note:</b> if the name you are trying to generate should be
278      * following a specific ordering, you should use the constructor
279      * with the ordering specified below.
280      */

281     public X509Name(
282         Hashtable JavaDoc attributes)
283     {
284         this(null, attributes);
285     }
286
287     /**
288      * Constructor from a table of attributes with ordering.
289      * <p>
290      * it's is assumed the table contains OID/String pairs, and the contents
291      * of the table are copied into an internal table as part of the
292      * construction process. The ordering vector should contain the OIDs
293      * in the order they are meant to be encoded or printed in toString.
294      */

295     public X509Name(
296         Vector JavaDoc ordering,
297         Hashtable JavaDoc attributes)
298     {
299         this(ordering, attributes, new X509DefaultEntryConverter());
300     }
301
302     /**
303      * Constructor from a table of attributes with ordering.
304      * <p>
305      * it's is assumed the table contains OID/String pairs, and the contents
306      * of the table are copied into an internal table as part of the
307      * construction process. The ordering vector should contain the OIDs
308      * in the order they are meant to be encoded or printed in toString.
309      * <p>
310      * The passed in converter will be used to convert the strings into their
311      * ASN.1 counterparts.
312      */

313     public X509Name(
314         Vector JavaDoc ordering,
315         Hashtable JavaDoc attributes,
316         X509DefaultEntryConverter converter)
317     {
318         this.converter = converter;
319
320         if (ordering != null)
321         {
322             for (int i = 0; i != ordering.size(); i++)
323             {
324                 this.ordering.addElement(ordering.elementAt(i));
325                 this.added.addElement(new Boolean JavaDoc(false));
326             }
327         }
328         else
329         {
330             Enumeration JavaDoc e = attributes.keys();
331
332             while (e.hasMoreElements())
333             {
334                 this.ordering.addElement(e.nextElement());
335                 this.added.addElement(new Boolean JavaDoc(false));
336             }
337         }
338
339         for (int i = 0; i != this.ordering.size(); i++)
340         {
341             DERObjectIdentifier oid = (DERObjectIdentifier)this.ordering.elementAt(i);
342
343             if (attributes.get(oid) == null)
344             {
345                 throw new IllegalArgumentException JavaDoc("No attribute for object id - " + oid.getId() + " - passed to distinguished name");
346             }
347
348             this.values.addElement(attributes.get(oid)); // copy the hash table
349
}
350     }
351
352     /**
353      * Takes two vectors one of the oids and the other of the values.
354      */

355     public X509Name(
356         Vector JavaDoc oids,
357         Vector JavaDoc values)
358     {
359         this(oids, values, new X509DefaultEntryConverter());
360     }
361
362     /**
363      * Takes two vectors one of the oids and the other of the values.
364      * <p>
365      * The passed in converter will be used to convert the strings into their
366      * ASN.1 counterparts.
367      */

368     public X509Name(
369         Vector JavaDoc oids,
370         Vector JavaDoc values,
371         X509NameEntryConverter converter)
372     {
373         this.converter = converter;
374
375         if (oids.size() != values.size())
376         {
377             throw new IllegalArgumentException JavaDoc("oids vector must be same length as values.");
378         }
379
380         for (int i = 0; i < oids.size(); i++)
381         {
382             this.ordering.addElement(oids.elementAt(i));
383             this.values.addElement(values.elementAt(i));
384             this.added.addElement(new Boolean JavaDoc(false));
385         }
386     }
387
388     /**
389      * Takes an X509 dir name as a string of the format "C=AU, ST=Victoria", or
390      * some such, converting it into an ordered set of name attributes.
391      */

392     public X509Name(
393         String JavaDoc dirName)
394     {
395         this(DefaultReverse, DefaultLookUp, dirName);
396     }
397
398     /**
399      * Takes an X509 dir name as a string of the format "C=AU, ST=Victoria", or
400      * some such, converting it into an ordered set of name attributes with each
401      * string value being converted to its associated ASN.1 type using the passed
402      * in converter.
403      */

404     public X509Name(
405         String JavaDoc dirName,
406         X509NameEntryConverter converter)
407     {
408         this(DefaultReverse, DefaultLookUp, dirName, converter);
409     }
410
411     /**
412      * Takes an X509 dir name as a string of the format "C=AU, ST=Victoria", or
413      * some such, converting it into an ordered set of name attributes. If reverse
414      * is true, create the encoded version of the sequence starting from the
415      * last element in the string.
416      */

417     public X509Name(
418         boolean reverse,
419         String JavaDoc dirName)
420     {
421         this(reverse, DefaultLookUp, dirName);
422     }
423
424     /**
425      * Takes an X509 dir name as a string of the format "C=AU, ST=Victoria", or
426      * some such, converting it into an ordered set of name attributes with each
427      * string value being converted to its associated ASN.1 type using the passed
428      * in converter. If reverse is true the ASN.1 sequence representing the DN will
429      * be built by starting at the end of the string, rather than the start.
430      */

431     public X509Name(
432         boolean reverse,
433         String JavaDoc dirName,
434         X509NameEntryConverter converter)
435     {
436         this(reverse, DefaultLookUp, dirName, converter);
437     }
438
439     /**
440      * Takes an X509 dir name as a string of the format "C=AU, ST=Victoria", or
441      * some such, converting it into an ordered set of name attributes. lookUp
442      * should provide a table of lookups, indexed by lowercase only strings and
443      * yielding a DERObjectIdentifier, other than that OID. and numeric oids
444      * will be processed automatically.
445      * <br>
446      * If reverse is true, create the encoded version of the sequence
447      * starting from the last element in the string.
448      * @param reverse true if we should start scanning from the end (RFC 2553).
449      * @param lookUp table of names and their oids.
450      * @param dirName the X.500 string to be parsed.
451      */

452     public X509Name(
453         boolean reverse,
454         Hashtable JavaDoc lookUp,
455         String JavaDoc dirName)
456     {
457         this(reverse, lookUp, dirName, new X509DefaultEntryConverter());
458     }
459
460     private DERObjectIdentifier decodeOID(
461         String JavaDoc name,
462         Hashtable JavaDoc lookUp)
463     {
464         if (name.toUpperCase().startsWith("OID."))
465         {
466             return new DERObjectIdentifier(name.substring(4));
467         }
468         else if (name.charAt(0) >= '0' && name.charAt(0) <= '9')
469         {
470             return new DERObjectIdentifier(name);
471         }
472
473         DERObjectIdentifier oid = (DERObjectIdentifier)lookUp.get(name.toLowerCase());
474         if (oid == null)
475         {
476             throw new IllegalArgumentException JavaDoc("Unknown object id - " + name + " - passed to distinguished name");
477         }
478
479         return oid;
480     }
481
482     /**
483      * Takes an X509 dir name as a string of the format "C=AU, ST=Victoria", or
484      * some such, converting it into an ordered set of name attributes. lookUp
485      * should provide a table of lookups, indexed by lowercase only strings and
486      * yielding a DERObjectIdentifier, other than that OID. and numeric oids
487      * will be processed automatically. The passed in converter is used to convert the
488      * string values to the right of each equals sign to their ASN.1 counterparts.
489      * <br>
490      * @param reverse true if we should start scanning from the end, false otherwise.
491      * @param lookUp table of names and oids.
492      * @param dirName the string dirName
493      * @param converter the converter to convert string values into their ASN.1 equivalents
494      */

495     public X509Name(
496         boolean reverse,
497         Hashtable JavaDoc lookUp,
498         String JavaDoc dirName,
499         X509NameEntryConverter converter)
500     {
501         this.converter = converter;
502         X509NameTokenizer nTok = new X509NameTokenizer(dirName);
503
504         while (nTok.hasMoreTokens())
505         {
506             String JavaDoc token = nTok.nextToken();
507             int index = token.indexOf('=');
508
509             if (index == -1)
510             {
511                 throw new IllegalArgumentException JavaDoc("badly formated directory string");
512             }
513
514             String JavaDoc name = token.substring(0, index);
515             String JavaDoc value = token.substring(index + 1);
516             DERObjectIdentifier oid = decodeOID(name, lookUp);
517
518             if (value.indexOf('+') > 0)
519             {
520                 X509NameTokenizer vTok = new X509NameTokenizer(value, '+');
521
522                 this.ordering.addElement(oid);
523                 this.values.addElement(vTok.nextToken());
524                 this.added.addElement(new Boolean JavaDoc(false));
525
526                 while (vTok.hasMoreTokens())
527                 {
528                     String JavaDoc sv = vTok.nextToken();
529                     int ndx = sv.indexOf('=');
530
531                     String JavaDoc nm = sv.substring(0, ndx);
532                     String JavaDoc vl = sv.substring(ndx + 1);
533                     this.ordering.addElement(decodeOID(nm, lookUp));
534                     this.values.addElement(vl);
535                     this.added.addElement(new Boolean JavaDoc(true));
536                 }
537             }
538             else
539             {
540                 this.ordering.addElement(oid);
541                 this.values.addElement(value);
542                 this.added.addElement(new Boolean JavaDoc(false));
543             }
544         }
545
546         if (reverse)
547         {
548             Vector JavaDoc o = new Vector JavaDoc();
549             Vector JavaDoc v = new Vector JavaDoc();
550             Vector JavaDoc a = new Vector JavaDoc();
551
552             for (int i = this.ordering.size() - 1; i >= 0; i--)
553             {
554                 o.addElement(this.ordering.elementAt(i));
555                 v.addElement(this.values.elementAt(i));
556                 a.addElement(this.added.elementAt(i));
557             }
558
559             this.ordering = o;
560             this.values = v;
561             this.added = a;
562         }
563     }
564
565     /**
566      * return a vector of the oids in the name, in the order they were found.
567      */

568     public Vector JavaDoc getOIDs()
569     {
570         Vector JavaDoc v = new Vector JavaDoc();
571
572         for (int i = 0; i != ordering.size(); i++)
573         {
574             v.addElement(ordering.elementAt(i));
575         }
576
577         return v;
578     }
579
580     /**
581      * return a vector of the values found in the name, in the order they
582      * were found.
583      */

584     public Vector JavaDoc getValues()
585     {
586         Vector JavaDoc v = new Vector JavaDoc();
587
588         for (int i = 0; i != values.size(); i++)
589         {
590             v.addElement(values.elementAt(i));
591         }
592
593         return v;
594     }
595
596     public DERObject toASN1Object()
597     {
598         if (seq == null)
599         {
600             ASN1EncodableVector vec = new ASN1EncodableVector();
601             ASN1EncodableVector sVec = new ASN1EncodableVector();
602             DERObjectIdentifier lstOid = null;
603
604             for (int i = 0; i != ordering.size(); i++)
605             {
606                 ASN1EncodableVector v = new ASN1EncodableVector();
607                 DERObjectIdentifier oid = (DERObjectIdentifier)ordering.elementAt(i);
608
609                 v.add(oid);
610
611                 String JavaDoc str = (String JavaDoc)values.elementAt(i);
612
613                 v.add(converter.getConvertedValue(oid, str));
614
615                 if (lstOid == null
616                     || ((Boolean JavaDoc)this.added.elementAt(i)).booleanValue())
617                 {
618                     sVec.add(new DERSequence(v));
619                 }
620                 else
621                 {
622                     vec.add(new DERSet(sVec));
623                     sVec = new ASN1EncodableVector();
624
625                     sVec.add(new DERSequence(v));
626                 }
627
628                 lstOid = oid;
629             }
630
631             vec.add(new DERSet(sVec));
632
633             seq = new DERSequence(vec);
634         }
635
636         return seq;
637     }
638
639     /**
640      * @param inOrder if true the order of both X509 names must be the same,
641      * as well as the values associated with each element.
642      */

643     public boolean equals(Object JavaDoc _obj, boolean inOrder)
644     {
645         if (_obj == this)
646         {
647             return true;
648         }
649
650         if (!inOrder)
651         {
652             return this.equals(_obj);
653         }
654
655         if (_obj == null || !(_obj instanceof X509Name))
656         {
657             return false;
658         }
659
660         X509Name _oxn = (X509Name)_obj;
661         int _orderingSize = ordering.size();
662
663         if (_orderingSize != _oxn.ordering.size())
664         {
665             return false;
666         }
667
668         for(int i = 0; i < _orderingSize; i++)
669         {
670             String JavaDoc _oid = ((DERObjectIdentifier)ordering.elementAt(i)).getId();
671             String JavaDoc _val = (String JavaDoc)values.elementAt(i);
672
673             String JavaDoc _oOID = ((DERObjectIdentifier)_oxn.ordering.elementAt(i)).getId();
674             String JavaDoc _oVal = (String JavaDoc)_oxn.values.elementAt(i);
675
676             if (_oid.equals(_oOID))
677             {
678                 _val = _val.trim().toLowerCase();
679                 _oVal = _oVal.trim().toLowerCase();
680                 if (_val.equals(_oVal))
681                 {
682                     continue;
683                 }
684                 else
685                 {
686                     StringBuffer JavaDoc v1 = new StringBuffer JavaDoc();
687                     StringBuffer JavaDoc v2 = new StringBuffer JavaDoc();
688
689                     if (_val.length() != 0)
690                     {
691                         char c1 = _val.charAt(0);
692
693                         v1.append(c1);
694
695                         for (int k = 1; k < _val.length(); k++)
696                         {
697                             char c2 = _val.charAt(k);
698                             if (!(c1 == ' ' && c2 == ' '))
699                             {
700                                 v1.append(c2);
701                             }
702                             c1 = c2;
703                         }
704                     }
705
706                     if (_oVal.length() != 0)
707                     {
708                         char c1 = _oVal.charAt(0);
709
710                         v2.append(c1);
711
712                         for (int k = 1; k < _oVal.length(); k++)
713                         {
714                             char c2 = _oVal.charAt(k);
715                             if (!(c1 == ' ' && c2 == ' '))
716                             {
717                                 v2.append(c2);
718                             }
719                             c1 = c2;
720                         }
721                     }
722
723                     if (!v1.toString().equals(v2.toString()))
724                     {
725                         return false;
726                     }
727                 }
728             }
729             else
730             {
731                 return false;
732             }
733         }
734
735         return true;
736     }
737
738     /**
739      * test for equality - note: case is ignored.
740      */

741     public boolean equals(Object JavaDoc _obj)
742     {
743         if (_obj == this)
744         {
745             return true;
746         }
747
748         if (_obj == null || !(_obj instanceof X509Name))
749         {
750             return false;
751         }
752
753         X509Name _oxn = (X509Name)_obj;
754
755         if (this.getDERObject().equals(_oxn.getDERObject()))
756         {
757             return true;
758         }
759
760         int _orderingSize = ordering.size();
761
762         if (_orderingSize != _oxn.ordering.size())
763         {
764             return false;
765         }
766
767         boolean[] _indexes = new boolean[_orderingSize];
768
769         for(int i = 0; i < _orderingSize; i++)
770         {
771             boolean _found = false;
772             String JavaDoc _oid = ((DERObjectIdentifier)ordering.elementAt(i)).getId();
773             String JavaDoc _val = (String JavaDoc)values.elementAt(i);
774
775             for(int j = 0; j < _orderingSize; j++)
776             {
777                 if(_indexes[j] == true)
778                 {
779                     continue;
780                 }
781
782                 String JavaDoc _oOID = ((DERObjectIdentifier)_oxn.ordering.elementAt(j)).getId();
783                 String JavaDoc _oVal = (String JavaDoc)_oxn.values.elementAt(j);
784
785                 if (_oid.equals(_oOID))
786                 {
787                     _val = _val.trim().toLowerCase();
788                     _oVal = _oVal.trim().toLowerCase();
789                     if (_val.equals(_oVal))
790                     {
791                         _indexes[j] = true;
792                         _found = true;
793                         break;
794                     }
795                     else
796                     {
797                         StringBuffer JavaDoc v1 = new StringBuffer JavaDoc();
798                         StringBuffer JavaDoc v2 = new StringBuffer JavaDoc();
799
800                         if (_val.length() != 0)
801                         {
802                             char c1 = _val.charAt(0);
803
804                             v1.append(c1);
805
806                             for (int k = 1; k < _val.length(); k++)
807                             {
808                                 char c2 = _val.charAt(k);
809                                 if (!(c1 == ' ' && c2 == ' '))
810                                 {
811                                     v1.append(c2);
812                                 }
813                                 c1 = c2;
814                             }
815                         }
816
817                         if (_oVal.length() != 0)
818                         {
819                             char c1 = _oVal.charAt(0);
820
821                             v2.append(c1);
822
823                             for (int k = 1; k < _oVal.length(); k++)
824                             {
825                                 char c2 = _oVal.charAt(k);
826                                 if (!(c1 == ' ' && c2 == ' '))
827                                 {
828                                     v2.append(c2);
829                                 }
830                                 c1 = c2;
831                             }
832                         }
833
834                         if (v1.toString().equals(v2.toString()))
835                         {
836                             _indexes[j] = true;
837                             _found = true;
838                             break;
839                         }
840                     }
841                 }
842             }
843
844             if(!_found)
845             {
846                 return false;
847             }
848         }
849
850         return true;
851     }
852
853     public int hashCode()
854     {
855         ASN1Sequence seq = (ASN1Sequence)this.getDERObject();
856         Enumeration JavaDoc e = seq.getObjects();
857         int hashCode = 0;
858
859         while (e.hasMoreElements())
860         {
861             hashCode ^= e.nextElement().hashCode();
862         }
863
864         return hashCode;
865     }
866
867     private void appendValue(
868         StringBuffer JavaDoc buf,
869         Hashtable JavaDoc oidSymbols,
870         DERObjectIdentifier oid,
871         String JavaDoc value)
872     {
873         String JavaDoc sym = (String JavaDoc)oidSymbols.get(oid);
874
875         if (sym != null)
876         {
877             buf.append(sym);
878         }
879         else
880         {
881             buf.append(oid.getId());
882         }
883
884         buf.append("=");
885
886         int index = buf.length();
887
888         buf.append(value);
889
890         int end = buf.length();
891
892         while (index != end)
893         {
894             if ((buf.charAt(index) == ',')
895                || (buf.charAt(index) == '"')
896                || (buf.charAt(index) == '\\')
897                || (buf.charAt(index) == '+')
898                || (buf.charAt(index) == '<')
899                || (buf.charAt(index) == '>')
900                || (buf.charAt(index) == ';'))
901             {
902                 buf.insert(index, "\\");
903                 index++;
904                 end++;
905             }
906
907             index++;
908         }
909     }
910
911     /**
912      * convert the structure to a string - if reverse is true the
913      * oids and values are listed out starting with the last element
914      * in the sequence (ala RFC 2253), otherwise the string will begin
915      * with the first element of the structure. If no string definition
916      * for the oid is found in oidSymbols the string value of the oid is
917      * added. Two standard symbol tables are provided DefaultSymbols, and
918      * RFC2253Symbols as part of this class.
919      *
920      * @param reverse if true start at the end of the sequence and work back.
921      * @param oidSymbols look up table strings for oids.
922      */

923     public String JavaDoc toString(
924         boolean reverse,
925         Hashtable JavaDoc oidSymbols)
926     {
927         StringBuffer JavaDoc buf = new StringBuffer JavaDoc();
928         boolean first = true;
929
930         if (reverse)
931         {
932             for (int i = ordering.size() - 1; i >= 0; i--)
933             {
934                 if (first)
935                 {
936                     first = false;
937                 }
938                 else
939                 {
940                     if (((Boolean JavaDoc)added.elementAt(i + 1)).booleanValue())
941                     {
942                         buf.append("+");
943                     }
944                     else
945                     {
946                         buf.append(",");
947                     }
948                 }
949
950                 appendValue(buf, oidSymbols,
951                             (DERObjectIdentifier)ordering.elementAt(i),
952                             (String JavaDoc)values.elementAt(i));
953             }
954         }
955         else
956         {
957             for (int i = 0; i < ordering.size(); i++)
958             {
959                 if (first)
960                 {
961                     first = false;
962                 }
963                 else
964                 {
965                     if (((Boolean JavaDoc)added.elementAt(i)).booleanValue())
966                     {
967                         buf.append("+");
968                     }
969                     else
970                     {
971                         buf.append(",");
972                     }
973                 }
974
975                 appendValue(buf, oidSymbols,
976                             (DERObjectIdentifier)ordering.elementAt(i),
977                             (String JavaDoc)values.elementAt(i));
978             }
979         }
980
981         return buf.toString();
982     }
983
984     public String JavaDoc toString()
985     {
986         return toString(DefaultReverse, DefaultSymbols);
987     }
988 }
989
Popular Tags