Home » geronimo-2.2-source-release » org.apache.geronimo.crypto.asn1.x509 » [javadoc | source]

    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.crypto.asn1.x509;
   19   
   20   import java.util.Enumeration;
   21   import java.util.Hashtable;
   22   import java.util.Vector;
   23   
   24   import org.apache.geronimo.crypto.asn1;
   25   import org.apache.geronimo.crypto.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 OIDLookUp = new Hashtable();
  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 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 RFC2253Symbols = new Hashtable();
  139   
  140       /**
  141        * look up table translating string values into their OIDS -
  142        * this static is scheduled for deletion
  143        */
  144       public static Hashtable SymbolLookUp = new Hashtable();
  145   
  146       /**
  147        * look up table translating common symbols into their OIDS.
  148        */
  149       public static Hashtable 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                  ordering = new Vector();
  209       private Vector                  values = new Vector();
  210       private Vector                  added = new Vector();
  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  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("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 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(true) : new Boolean(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  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      ordering,
  297           Hashtable   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                      ordering,
  315           Hashtable                   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(false));
  326               }
  327           }
  328           else
  329           {
  330               Enumeration     e = attributes.keys();
  331   
  332               while (e.hasMoreElements())
  333               {
  334                   this.ordering.addElement(e.nextElement());
  335                   this.added.addElement(new Boolean(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("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  oids,
  357           Vector  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                  oids,
  370           Vector                  values,
  371           X509NameEntryConverter  converter)
  372       {
  373           this.converter = converter;
  374   
  375           if (oids.size() != values.size())
  376           {
  377               throw new IllegalArgumentException("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(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  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                  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  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                  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   lookUp,
  455           String      dirName)
  456       {
  457           this(reverse, lookUp, dirName, new X509DefaultEntryConverter());
  458       }
  459   
  460       private DERObjectIdentifier decodeOID(
  461           String      name,
  462           Hashtable   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("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               lookUp,
  498           String                  dirName,
  499           X509NameEntryConverter  converter)
  500       {
  501           this.converter = converter;
  502           X509NameTokenizer   nTok = new X509NameTokenizer(dirName);
  503   
  504           while (nTok.hasMoreTokens())
  505           {
  506               String  token = nTok.nextToken();
  507               int     index = token.indexOf('=');
  508   
  509               if (index == -1)
  510               {
  511                   throw new IllegalArgumentException("badly formated directory string");
  512               }
  513   
  514               String              name = token.substring(0, index);
  515               String              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(false));
  525   
  526                   while (vTok.hasMoreTokens())
  527                   {
  528                       String  sv = vTok.nextToken();
  529                       int     ndx = sv.indexOf('=');
  530   
  531                       String  nm = sv.substring(0, ndx);
  532                       String  vl = sv.substring(ndx + 1);
  533                       this.ordering.addElement(decodeOID(nm, lookUp));
  534                       this.values.addElement(vl);
  535                       this.added.addElement(new Boolean(true));
  536                   }
  537               }
  538               else
  539               {
  540                   this.ordering.addElement(oid);
  541                   this.values.addElement(value);
  542                   this.added.addElement(new Boolean(false));
  543               }
  544           }
  545   
  546           if (reverse)
  547           {
  548               Vector  o = new Vector();
  549               Vector  v = new Vector();
  550               Vector  a = new Vector();
  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 getOIDs()
  569       {
  570           Vector  v = new Vector();
  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 getValues()
  585       {
  586           Vector  v = new Vector();
  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  str = (String)values.elementAt(i);
  612   
  613                   v.add(converter.getConvertedValue(oid, str));
  614   
  615                   if (lstOid == null
  616                       || ((Boolean)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 _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  _oid   = ((DERObjectIdentifier)ordering.elementAt(i)).getId();
  671               String  _val   = (String)values.elementAt(i);
  672   
  673               String _oOID = ((DERObjectIdentifier)_oxn.ordering.elementAt(i)).getId();
  674               String _oVal = (String)_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    v1 = new StringBuffer();
  687                       StringBuffer    v2 = new StringBuffer();
  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 _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  _oid   = ((DERObjectIdentifier)ordering.elementAt(i)).getId();
  773               String  _val   = (String)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 _oOID = ((DERObjectIdentifier)_oxn.ordering.elementAt(j)).getId();
  783                   String _oVal = (String)_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    v1 = new StringBuffer();
  798                           StringBuffer    v2 = new StringBuffer();
  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   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        buf,
  869           Hashtable           oidSymbols,
  870           DERObjectIdentifier oid,
  871           String              value)
  872       {
  873           String  sym = (String)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 toString(
  924           boolean     reverse,
  925           Hashtable   oidSymbols)
  926       {
  927           StringBuffer            buf = new StringBuffer();
  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)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)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)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)values.elementAt(i));
  978               }
  979           }
  980   
  981           return buf.toString();
  982       }
  983   
  984       public String toString()
  985       {
  986           return toString(DefaultReverse, DefaultSymbols);
  987       }
  988   }

Home » geronimo-2.2-source-release » org.apache.geronimo.crypto.asn1.x509 » [javadoc | source]