resolve darcs stupidity
[org.ibex.core.git] / src / org / bouncycastle / asn1 / x509 / X509Name.java
index 2f2a60f..e5019b6 100644 (file)
@@ -1,6 +1,5 @@
 package org.bouncycastle.asn1.x509;
 
-import java.io.*;
 import java.util.*;
 
 import org.bouncycastle.asn1.*;
@@ -24,6 +23,11 @@ public class X509Name
     public static final DERObjectIdentifier OU = new DERObjectIdentifier("2.5.4.11");
 
     /**
+     * Title
+     */
+    public static final DERObjectIdentifier T = new DERObjectIdentifier("2.5.4.12");
+
+    /**
      * common name - StringType(SIZE(1..64))
      */
     public static final DERObjectIdentifier CN = new DERObjectIdentifier("2.5.4.3");
@@ -43,12 +47,28 @@ public class X509Name
      */
     public static final DERObjectIdentifier ST = new DERObjectIdentifier("2.5.4.8");
 
+
     /**
      * email address (RSA PKCS#9 extension) - IA5String
      * <p>
      * note: if you're trying to be ultra orthodox, don't use this! It shouldn't be in here.
      */
     public static final DERObjectIdentifier EmailAddress = new DERObjectIdentifier("1.2.840.113549.1.9.1");
+        
+        /**
+         * email address in Verisign certificates
+         */
+        public static final DERObjectIdentifier E = EmailAddress;
+        
+    /*
+     * others...
+     */
+    public static final DERObjectIdentifier DC = new DERObjectIdentifier("0.9.2342.19200300.100.1.25");
+
+    /**
+     * LDAP User id.
+     */
+    public static final DERObjectIdentifier UID = new DERObjectIdentifier("0.9.2342.19200300.100.1.1");
 
     /**
      * look up table translating OID values into their common symbols.
@@ -64,46 +84,75 @@ public class X509Name
     {
         OIDLookUp.put(C, "C");
         OIDLookUp.put(O, "O");
+        OIDLookUp.put(T, "T");
         OIDLookUp.put(OU, "OU");
         OIDLookUp.put(CN, "CN");
         OIDLookUp.put(L, "L");
         OIDLookUp.put(ST, "ST");
         OIDLookUp.put(SN, "SN");
-        OIDLookUp.put(EmailAddress, "EmailAddress");
-
-        SymbolLookUp.put("C", C);
-        SymbolLookUp.put("O", O);
-        SymbolLookUp.put("OU", OU);
-        SymbolLookUp.put("CN", CN);
-        SymbolLookUp.put("L", L);
-        SymbolLookUp.put("ST", ST);
-        SymbolLookUp.put("SN", SN);
-        SymbolLookUp.put("EmailAddress", EmailAddress);
+        OIDLookUp.put(EmailAddress, "E");
+        OIDLookUp.put(DC, "DC");
+        OIDLookUp.put(UID, "UID");
+
+        SymbolLookUp.put("c", C);
+        SymbolLookUp.put("o", O);
+        SymbolLookUp.put("t", T);
+        SymbolLookUp.put("ou", OU);
+        SymbolLookUp.put("cn", CN);
+        SymbolLookUp.put("l", L);
+        SymbolLookUp.put("st", ST);
+        SymbolLookUp.put("sn", SN);
+        SymbolLookUp.put("emailaddress", E);
+        SymbolLookUp.put("dc", DC);
+        SymbolLookUp.put("e", E);
+        SymbolLookUp.put("uid", UID);
     }
 
     private Vector                  ordering = new Vector();
-    private Hashtable               attributes = new Hashtable();
-    private DERConstructedSequence  seq = null;
+    private Vector                  values = new Vector();
+    private ASN1Sequence            seq;
+
+    public static X509Name getInstance(
+        ASN1TaggedObject obj,
+        boolean          explicit)
+    {
+        return getInstance(ASN1Sequence.getInstance(obj, explicit));
+    }
+
+    public static X509Name getInstance(
+        Object  obj)
+    {
+        if (obj == null || obj instanceof X509Name)
+        {
+            return (X509Name)obj;
+        }
+        else if (obj instanceof ASN1Sequence)
+        {
+            return new X509Name((ASN1Sequence)obj);
+        }
+
+        throw new IllegalArgumentException("unknown object in factory");
+    }
 
     /**
-     * Constructor from DERConstructedSequence.
+     * Constructor from ASN1Sequence
      *
      * the principal will be a list of constructed sets, each containing an (OID, String) pair.
      */
     public X509Name(
-        DERConstructedSequence  seq)
+        ASN1Sequence  seq)
     {
-        this.seq = seq; 
+        this.seq = seq;
 
         Enumeration e = seq.getObjects();
 
         while (e.hasMoreElements())
         {
-            DERSet  set = (DERSet)e.nextElement();
-            DERConstructedSequence  s = (DERConstructedSequence)set.getSequence();
+            ASN1Set         set = (ASN1Set)e.nextElement();
+            ASN1Sequence    s = (ASN1Sequence)set.getObjectAt(0);
 
             ordering.addElement(s.getObjectAt(0));
-            attributes.put(s.getObjectAt(0), ((DERString)s.getObjectAt(1)).getString());
+            values.addElement(((DERString)s.getObjectAt(1)).getString());
         }
     }
 
@@ -167,7 +216,26 @@ public class X509Name
                 throw new IllegalArgumentException("No attribute for object id - " + oid.getId() + " - passed to distinguished name");
             }
 
-            this.attributes.put(oid, attributes.get(oid)); // copy the hash table
+            this.values.addElement(attributes.get(oid)); // copy the hash table
+        }
+    }
+
+    /**
+     * takes two vectors one of the oids and the other of the values.
+     */
+    public X509Name(
+        Vector  ordering,
+        Vector  values)
+    {
+        if (ordering.size() != values.size())
+        {
+            throw new IllegalArgumentException("ordering vector must be same length as values.");
+        }
+
+        for (int i = 0; i < ordering.size(); i++)
+        {
+            this.ordering.addElement(ordering.elementAt(i));
+            this.values.addElement(values.elementAt(i));
         }
     }
 
@@ -190,123 +258,175 @@ public class X509Name
                 throw new IllegalArgumentException("badly formated directory string");
             }
 
-            String  name = token.substring(0, index);
-            String  value = token.substring(index + 1);
+            String              name = token.substring(0, index);
+            String              value = token.substring(index + 1);
+            DERObjectIdentifier oid = null;
 
-            DERObjectIdentifier oid = (DERObjectIdentifier)SymbolLookUp.get(name);
-            if (oid == null)
+            if (name.toUpperCase().startsWith("OID."))
             {
-                throw new IllegalArgumentException("Unknown object id - " + oid.getId() + " - passed to distinguished name");
+                oid = new DERObjectIdentifier(name.substring(4));
+            }
+            else if (name.charAt(0) >= '0' && name.charAt(0) <= '9')
+            {
+                oid = new DERObjectIdentifier(name);
+            }
+            else
+            {
+                oid = (DERObjectIdentifier)SymbolLookUp.get(name.toLowerCase());
+                if (oid == null)
+                {
+                    throw new IllegalArgumentException("Unknown object id - " + name + " - passed to distinguished name");
+                }
             }
 
             this.ordering.addElement(oid);
-            this.attributes.put(oid, value);
+            this.values.addElement(value);
         }
     }
 
+    /**
+     * return false if we have characters out of the range of a printable
+     * string, true otherwise.
+     */
+    private boolean canBePrintable(
+        String  str)
+    {
+        for (int i = str.length() - 1; i >= 0; i--)
+        {
+            if (str.charAt(i) > 0x007f)
+            {
+                return false;
+            }
+        }
+
+        return true;
+    }
+
     public DERObject getDERObject()
     {
         if (seq == null)
         {
-            seq = new DERConstructedSequence();
+            DEREncodableVector  vec = new DEREncodableVector();
 
             for (int i = 0; i != ordering.size(); i++)
             {
-                DERConstructedSequence  s = new DERConstructedSequence();
+                DEREncodableVector      v = new DEREncodableVector();
                 DERObjectIdentifier     oid = (DERObjectIdentifier)ordering.elementAt(i);
 
-                s.addObject(oid);
+                v.add(oid);
+
+                String  str = (String)values.elementAt(i);
+
                 if (oid.equals(EmailAddress))
                 {
-                    s.addObject(new DERIA5String((String)attributes.get(oid)));
+                    v.add(new DERIA5String(str));
                 }
                 else
                 {
-                    s.addObject(new DERPrintableString((String)attributes.get(oid)));
+                    if (canBePrintable(str))
+                    {
+                        v.add(new DERPrintableString(str));
+                    }
+                    else
+                    {
+                        v.add(new DERUTF8String(str));
+                    }
                 }
 
-                seq.addObject(new DERSet(s));
+                vec.add(new DERSet(new DERSequence(v)));
             }
-        }
 
-        return seq;
-    }
-
-    public int hashCode()
-    {
-        Enumeration     e = attributes.keys();
-        int             hashCode = 0;
-
-        while (e.hasMoreElements())
-        {
-            Object  o = e.nextElement();
-
-            hashCode ^= o.hashCode();
-            hashCode ^= attributes.get(o).hashCode();
+            seq = new DERSequence(vec);
         }
 
-        for (int i = 0; i != ordering.size(); i++)
-        {
-            hashCode ^= ordering.elementAt(i).hashCode();
-        }
-
-        return hashCode;
+        return seq;
     }
 
-    public boolean equals(
-        Object o)
+    /**
+     * test for equality - note: case is ignored.
+     */
+    public boolean equals(Object _obj) 
     {
-        if (o == null || !(o instanceof X509Name))
+        if (_obj == this)
         {
-            return false;
+            return true;
         }
 
-        X509Name        other = (X509Name)o;
-
-        if (ordering.size() != other.ordering.size())
+        if (_obj == null || !(_obj instanceof X509Name))
         {
             return false;
         }
+        
+        X509Name _oxn          = (X509Name)_obj;
+        int      _orderingSize = ordering.size();
 
-        for (int i = 0; i != ordering.size(); i++)
+        if (_orderingSize != _oxn.ordering.size()) 
         {
-            if (!ordering.elementAt(i).equals(other.ordering.elementAt(i)))
-            {
-                return false;
-            }
-        }
-
-        Enumeration     e1 = attributes.keys();
-        Enumeration     e2 = other.attributes.keys();
+                        return false;
+                }
+                
+                boolean[] _indexes = new boolean[_orderingSize];
 
-        while (e1.hasMoreElements() && e2.hasMoreElements())
-        {
-            Object  o1 = e1.nextElement();
-            Object  o2 = e2.nextElement();
-            
-            if (!o1.equals(o2))
-            {
-                return false;
-            }
+                for(int i = 0; i < _orderingSize; i++) 
+                {
+                        boolean _found = false;
+                        String  _oid   = ((DERObjectIdentifier)ordering.elementAt(i)).getId();
+                        String  _val   = (String)values.elementAt(i);
+                        
+                        for(int j = 0; j < _orderingSize; j++) 
+                        {
+                                if(_indexes[j] == true)
+                                {
+                                        continue;
+                                }
+                                
+                                String _oOID = ((DERObjectIdentifier)_oxn.ordering.elementAt(j)).getId();
+                                String _oVal = (String)_oxn.values.elementAt(j);
+
+                // was equalsIgnoreCase but MIDP doesn't like that.
+                                if(_oid.equals(_oOID) && _val.toLowerCase().equals(_oVal.toLowerCase()))
+                                {
+                                        _indexes[j] = true;
+                                        _found      = true;
+                                        break;
+                                }
+
+                        }
+
+                        if(!_found)
+                        {
+                                return false;
+                        }
+                }
+                
+                return true;
         }
+        
+    public int hashCode()
+    {
+        ASN1Sequence  seq = (ASN1Sequence)this.getDERObject();
+        Enumeration   e = seq.getObjects();
+        int           hashCode = 0;
 
-        if (e1.hasMoreElements() || e2.hasMoreElements())
+        while (e.hasMoreElements())
         {
-            return false;
+            hashCode ^= e.nextElement().hashCode();
         }
 
-        return true;
+        return hashCode;
     }
 
     public String toString()
     {
-        StringBuffer    buf = new StringBuffer();
-        boolean         first = true;
+        StringBuffer            buf = new StringBuffer();
+        boolean                 first = true;
+        Enumeration             e1 = ordering.elements();
+        Enumeration             e2 = values.elements();
 
-        for (int i = 0; i != ordering.size(); i++)
+        while (e1.hasMoreElements())
         {
-            Object  oid = ordering.elementAt(i);
-            String  sym = (String)OIDLookUp.get(oid);
+            Object                  oid = e1.nextElement();
+            String                  sym = (String)OIDLookUp.get(oid);
             
             if (first)
             {
@@ -314,20 +434,42 @@ public class X509Name
             }
             else
             {
-                buf.append(", ");
+                buf.append(",");
             }
 
             if (sym != null)
             {
                 buf.append(sym);
-                buf.append("=");
-                buf.append((String)attributes.get(oid));
             }
             else
             {
                 buf.append(((DERObjectIdentifier)oid).getId());
-                buf.append("=");
-                buf.append((String)attributes.get(oid));
+            }
+
+            buf.append("=");
+
+            int     index = buf.length();
+
+            buf.append((String)e2.nextElement());
+
+            int     end = buf.length();
+
+            while (index != end)
+            {
+                if ((buf.charAt(index) == ',')
+                   || (buf.charAt(index) == '"')
+                   || (buf.charAt(index) == '\\')
+                   || (buf.charAt(index) == '+')
+                   || (buf.charAt(index) == '<')
+                   || (buf.charAt(index) == '>')
+                   || (buf.charAt(index) == ';'))
+                {
+                    buf.insert(index, "\\");
+                    index++;
+                    end++;
+                }
+
+                index++;
             }
         }