2002/03/21 01:19:32
[org.ibex.core.git] / src / org / bouncycastle / asn1 / x509 / AuthorityKeyIdentifier.java
diff --git a/src/org/bouncycastle/asn1/x509/AuthorityKeyIdentifier.java b/src/org/bouncycastle/asn1/x509/AuthorityKeyIdentifier.java
new file mode 100644 (file)
index 0000000..9285c96
--- /dev/null
@@ -0,0 +1,172 @@
+package org.bouncycastle.asn1.x509;
+
+import java.math.BigInteger;
+
+import java.util.Enumeration;
+
+import org.bouncycastle.crypto.Digest;
+import org.bouncycastle.crypto.digests.SHA1Digest;
+import org.bouncycastle.asn1.*;
+
+/**
+ * <pre>
+ * id-ce-authorityKeyIdentifier OBJECT IDENTIFIER ::=  { id-ce 35 }
+ *
+ *   AuthorityKeyIdentifier ::= SEQUENCE {
+ *      keyIdentifier             [0] IMPLICIT KeyIdentifier           OPTIONAL,
+ *      authorityCertIssuer       [1] IMPLICIT GeneralNames            OPTIONAL,
+ *      authorityCertSerialNumber [2] IMPLICIT CertificateSerialNumber OPTIONAL  }
+ *
+ *   KeyIdentifier ::= OCTET STRING
+ * </pre>
+ *
+ */
+public class AuthorityKeyIdentifier
+    implements DEREncodable
+{
+    DEROctetString keyidentifier=null;
+    GeneralNames certissuer=null;
+    DERInteger certserno=null;
+
+    public AuthorityKeyIdentifier(
+        DERConstructedSequence   seq)
+    {
+        Enumeration e = seq.getObjects();
+
+        while (e.hasMoreElements())
+        {
+            DERTaggedObject o = (DERTaggedObject)e.nextElement();
+
+            switch (o.getTagNo())
+            {
+            case 0:
+                this.keyidentifier= (DEROctetString)o.getObject();
+                break;
+
+            case 1:
+                if (o.getObject() instanceof DERConstructedSequence)
+                {
+                    this.certissuer = new GeneralNames((DERConstructedSequence)o.getObject());
+                }
+                else   
+                {
+                    // as it's implicitly tagged we can loose the"sequence"
+                    // if there is only one object.
+                    //
+                    DERConstructedSequence s = new DERConstructedSequence();
+
+                    s.addObject(o.getObject());
+
+                    this.certissuer = new GeneralNames(s);
+                }
+                break;
+            case 2:
+                //
+                // implicit tagging again...
+                //
+                DEROctetString          oct = (DEROctetString)o.getObject();
+
+                this.certserno = new DERInteger(new BigInteger(oct.getOctets()));
+                break;
+            default:
+                throw new IllegalArgumentException("illegal tag");
+            }
+        }
+    }
+
+    /**
+     *
+     * Calulates the keyidentifier using a SHA1 hash over the BIT STRING
+     * from SubjectPublicKeyInfo as defined in RFC2459.
+     *
+     * Example of making a AuthorityKeyIdentifier:
+     * <pre>
+     *   SubjectPublicKeyInfo apki = new SubjectPublicKeyInfo((DERConstructedSequence)new DERInputStream(
+     *       new ByteArrayInputStream(publicKey.getEncoded())).readObject());
+     *   AuthorityKeyIdentifier aki = new AuthorityKeyIdentifier(apki);
+     * </pre>
+     *
+     **/
+    public AuthorityKeyIdentifier(
+        SubjectPublicKeyInfo    spki)
+    {
+        Digest  digest = new SHA1Digest();
+        byte[]  resBuf = new byte[digest.getDigestSize()];
+
+        DERBitString derpk = new DERBitString(spki.getPublicKey());
+        byte[] bytes = derpk.getBytes();
+        digest.update(bytes, 0, bytes.length);
+        digest.doFinal(resBuf, 0);
+        this.keyidentifier=new DEROctetString(resBuf);
+    }
+
+    /**
+     * create an AuthorityKeyIdentifier with the GeneralNames tag and
+     * the serial number provided as well.
+     */
+    public AuthorityKeyIdentifier(
+        SubjectPublicKeyInfo    spki,
+        GeneralNames            name,
+        BigInteger              serialNumber)
+    {
+        Digest  digest = new SHA1Digest();
+        byte[]  resBuf = new byte[digest.getDigestSize()];
+
+        DERBitString derpk = new DERBitString(spki.getPublicKey());
+        byte[] bytes = derpk.getBytes();
+        digest.update(bytes, 0, bytes.length);
+        digest.doFinal(resBuf, 0);
+
+        this.keyidentifier = new DEROctetString(resBuf);
+        this.certissuer = name;
+        this.certserno = new DERInteger(serialNumber);
+    }
+
+    public byte[] getKeyIdentifier()
+    {
+        if (keyidentifier != null)
+        {
+            return keyidentifier.getOctets();
+        }
+
+        return null;
+    }
+
+     /**
+     * <pre>
+     *   AuthorityKeyIdentifier ::= SEQUENCE {
+     *      keyIdentifier             [0] IMPLICIT KeyIdentifier           OPTIONAL,
+     *      authorityCertIssuer       [1] IMPLICIT GeneralNames            OPTIONAL,
+     *      authorityCertSerialNumber [2] IMPLICIT CertificateSerialNumber OPTIONAL  }
+     *
+     *   KeyIdentifier ::= OCTET STRING
+     * </pre>
+     */
+    public DERObject getDERObject()
+    {
+        DERConstructedSequence  seq = new DERConstructedSequence();
+
+        if (keyidentifier != null)
+        {
+            seq.addObject(new DERTaggedObject(false, 0, keyidentifier));
+        }
+
+        if (certissuer != null)
+        {
+            seq.addObject(new DERTaggedObject(false, 1, certissuer));
+        }
+
+        if (certserno != null)
+        {
+            seq.addObject(new DERTaggedObject(false, 2, certserno));
+        }
+
+
+        return seq;
+    }
+
+    public String toString()
+    {
+        return ("AuthorityKeyIdentifier: KeyID(" + this.keyidentifier.getOctets() + ")");
+    }
+}