fixed bug 534
[org.ibex.core.git] / src / org / bouncycastle / asn1 / DERObjectIdentifier.java
index 8f04454..fb16ac9 100644 (file)
@@ -7,6 +7,91 @@ public class DERObjectIdentifier
 {
     String      identifier;
 
+    /**
+     * return an OID from the passed in object
+     *
+     * @exception IllegalArgumentException if the object cannot be converted.
+     */
+    public static DERObjectIdentifier getInstance(
+        Object  obj)
+    {
+        if (obj == null || obj instanceof DERObjectIdentifier)
+        {
+            return (DERObjectIdentifier)obj;
+        }
+
+        if (obj instanceof ASN1OctetString)
+        {
+            return new DERObjectIdentifier(((ASN1OctetString)obj).getOctets());
+        }
+
+        if (obj instanceof ASN1TaggedObject)
+        {
+            return getInstance(((ASN1TaggedObject)obj).getObject());
+        }
+
+        throw new IllegalArgumentException("illegal object in getInstance: " + obj.getClass().getName());
+    }
+
+    /**
+     * return an Object Identifier from a tagged object.
+     *
+     * @param obj the tagged object holding the object we want
+     * @param explicit true if the object is meant to be explicitly
+     *              tagged false otherwise.
+     * @exception IllegalArgumentException if the tagged object cannot
+     *               be converted.
+     */
+    public static DERObjectIdentifier getInstance(
+        ASN1TaggedObject obj,
+        boolean          explicit)
+    {
+        return getInstance(obj.getObject());
+    }
+    
+
+    DERObjectIdentifier(
+        byte[]  bytes)
+    {
+        int             head = bytes[0] & 0xff;
+        StringBuffer    objId = new StringBuffer();
+        int             value = 0;
+        boolean         first = true;
+
+        for (int i = 0; i != bytes.length; i++)
+        {
+            int b = bytes[i] & 0xff;
+
+            value = value * 128 + (b & 0x7f);
+            if ((b & 0x80) == 0)             // end of number reached
+            {
+                if (first)
+                {
+                    switch (value / 40)
+                    {
+                    case 0:
+                        objId.append('0');
+                        break;
+                    case 1:
+                        objId.append('1');
+                        value -= 40;
+                        break;
+                    default:
+                        objId.append('2');
+                        value -= 80;
+                    }
+                    first = false;
+                }
+
+                objId.append('.');
+                objId.append(Integer.toString(value));
+                value = 0;
+            }
+        }
+
+        this.identifier = objId.toString();
+    }
+
     public DERObjectIdentifier(
         String  identifier)
     {
@@ -18,6 +103,30 @@ public class DERObjectIdentifier
         return identifier;
     }
 
+    private void writeField(
+        OutputStream    out,
+        int             fieldValue)
+        throws IOException
+    {
+        if (fieldValue >= (1 << 7))
+        {
+            if (fieldValue >= (1 << 14))
+            {
+                if (fieldValue >= (1 << 21))
+                {
+                    if (fieldValue >= (1 << 28))
+                    {
+                        out.write((fieldValue >> 28) | 0x80);
+                    }
+                    out.write((fieldValue >> 21) | 0x80);
+                }
+                out.write((fieldValue >> 14) | 0x80);
+            }
+            out.write((fieldValue >> 7) | 0x80);
+        }
+        out.write(fieldValue & 0x7f);
+    }
+
     void encode(
         DEROutputStream out)
         throws IOException
@@ -26,31 +135,13 @@ public class DERObjectIdentifier
         ByteArrayOutputStream   bOut = new ByteArrayOutputStream();
         DEROutputStream         dOut = new DEROutputStream(bOut);
 
-                                    // space for 5 7 bit numbers in an int
-        byte[]                  iBuf = new byte[5];    
-        
-        // FIXED by Adam Megacz -- GCJ doesn't handle evaluation order properly
-        String t1 = tok.nextToken();
-        String t2 = tok.nextToken();
-        dOut.write(Integer.parseInt(t1) * 40 + Integer.parseInt(t2));
+        writeField(bOut, 
+                    Integer.parseInt(tok.nextToken()) * 40
+                    + Integer.parseInt(tok.nextToken()));
 
         while (tok.hasMoreTokens())
         {
-            //
-            // translate into base 128
-            //
-            int value = Integer.parseInt(tok.nextToken());
-            int count = iBuf.length - 1;
-            
-            iBuf[count--] = (byte)(value % 128);
-            value /= 128;
-
-            while (value != 0)
-            {
-                iBuf[count--] = (byte)((value % 128) | 0x80);
-                value /= 128;
-            }
-            dOut.write(iBuf, count + 1, iBuf.length - (count + 1));
+            writeField(bOut, Integer.parseInt(tok.nextToken()));
         }
 
         dOut.close();