AuthorityKeyIdentifier.java revision e1142c149e244797ce73b0e7fad40816e447a817
1package org.bouncycastle.asn1.x509;
2
3import java.math.BigInteger;
4import java.util.Enumeration;
5
6import org.bouncycastle.asn1.ASN1EncodableVector;
7import org.bouncycastle.asn1.ASN1Integer;
8import org.bouncycastle.asn1.ASN1Object;
9import org.bouncycastle.asn1.ASN1OctetString;
10import org.bouncycastle.asn1.ASN1Primitive;
11import org.bouncycastle.asn1.ASN1Sequence;
12import org.bouncycastle.asn1.ASN1TaggedObject;
13import org.bouncycastle.asn1.DEROctetString;
14import org.bouncycastle.asn1.DERSequence;
15import org.bouncycastle.asn1.DERTaggedObject;
16import org.bouncycastle.crypto.Digest;
17// BEGIN android-changed
18import org.bouncycastle.crypto.digests.AndroidDigestFactory;
19// END android-changed
20
21/**
22 * The AuthorityKeyIdentifier object.
23 * <pre>
24 * id-ce-authorityKeyIdentifier OBJECT IDENTIFIER ::=  { id-ce 35 }
25 *
26 *   AuthorityKeyIdentifier ::= SEQUENCE {
27 *      keyIdentifier             [0] IMPLICIT KeyIdentifier           OPTIONAL,
28 *      authorityCertIssuer       [1] IMPLICIT GeneralNames            OPTIONAL,
29 *      authorityCertSerialNumber [2] IMPLICIT CertificateSerialNumber OPTIONAL  }
30 *
31 *   KeyIdentifier ::= OCTET STRING
32 * </pre>
33 *
34 */
35public class AuthorityKeyIdentifier
36    extends ASN1Object
37{
38    ASN1OctetString keyidentifier=null;
39    GeneralNames certissuer=null;
40    ASN1Integer certserno=null;
41
42    public static AuthorityKeyIdentifier getInstance(
43        ASN1TaggedObject obj,
44        boolean          explicit)
45    {
46        return getInstance(ASN1Sequence.getInstance(obj, explicit));
47    }
48
49    public static AuthorityKeyIdentifier getInstance(
50        Object  obj)
51    {
52        if (obj instanceof AuthorityKeyIdentifier)
53        {
54            return (AuthorityKeyIdentifier)obj;
55        }
56        if (obj != null)
57        {
58            return new AuthorityKeyIdentifier(ASN1Sequence.getInstance(obj));
59        }
60
61        return null;
62    }
63
64    public static AuthorityKeyIdentifier fromExtensions(Extensions extensions)
65    {
66         return AuthorityKeyIdentifier.getInstance(extensions.getExtensionParsedValue(Extension.authorityKeyIdentifier));
67    }
68
69    protected AuthorityKeyIdentifier(
70        ASN1Sequence   seq)
71    {
72        Enumeration     e = seq.getObjects();
73
74        while (e.hasMoreElements())
75        {
76            ASN1TaggedObject o = DERTaggedObject.getInstance(e.nextElement());
77
78            switch (o.getTagNo())
79            {
80            case 0:
81                this.keyidentifier = ASN1OctetString.getInstance(o, false);
82                break;
83            case 1:
84                this.certissuer = GeneralNames.getInstance(o, false);
85                break;
86            case 2:
87                this.certserno = ASN1Integer.getInstance(o, false);
88                break;
89            default:
90                throw new IllegalArgumentException("illegal tag");
91            }
92        }
93    }
94
95    /**
96     *
97     * Calulates the keyidentifier using a SHA1 hash over the BIT STRING
98     * from SubjectPublicKeyInfo as defined in RFC2459.
99     *
100     * Example of making a AuthorityKeyIdentifier:
101     * <pre>
102     *   SubjectPublicKeyInfo apki = new SubjectPublicKeyInfo((ASN1Sequence)new ASN1InputStream(
103     *       publicKey.getEncoded()).readObject());
104     *   AuthorityKeyIdentifier aki = new AuthorityKeyIdentifier(apki);
105     * </pre>
106     *
107     **/
108    public AuthorityKeyIdentifier(
109        SubjectPublicKeyInfo    spki)
110    {
111        // BEGIN android-changed
112        Digest  digest = AndroidDigestFactory.getSHA1();
113        // END android-changed
114        byte[]  resBuf = new byte[digest.getDigestSize()];
115
116        byte[] bytes = spki.getPublicKeyData().getBytes();
117        digest.update(bytes, 0, bytes.length);
118        digest.doFinal(resBuf, 0);
119        this.keyidentifier = new DEROctetString(resBuf);
120    }
121
122    /**
123     * create an AuthorityKeyIdentifier with the GeneralNames tag and
124     * the serial number provided as well.
125     */
126    public AuthorityKeyIdentifier(
127        SubjectPublicKeyInfo    spki,
128        GeneralNames            name,
129        BigInteger              serialNumber)
130    {
131        // BEGIN android-changed
132        Digest  digest = AndroidDigestFactory.getSHA1();
133        // END android-changed
134        byte[]  resBuf = new byte[digest.getDigestSize()];
135
136        byte[] bytes = spki.getPublicKeyData().getBytes();
137        digest.update(bytes, 0, bytes.length);
138        digest.doFinal(resBuf, 0);
139
140        this.keyidentifier = new DEROctetString(resBuf);
141        this.certissuer = GeneralNames.getInstance(name.toASN1Primitive());
142        this.certserno = new ASN1Integer(serialNumber);
143    }
144
145    /**
146     * create an AuthorityKeyIdentifier with the GeneralNames tag and
147     * the serial number provided.
148     */
149    public AuthorityKeyIdentifier(
150        GeneralNames            name,
151        BigInteger              serialNumber)
152    {
153        this.keyidentifier = null;
154        this.certissuer = GeneralNames.getInstance(name.toASN1Primitive());
155        this.certserno = new ASN1Integer(serialNumber);
156    }
157
158    /**
159      * create an AuthorityKeyIdentifier with a precomupted key identifier
160      */
161     public AuthorityKeyIdentifier(
162         byte[]                  keyIdentifier)
163     {
164         this.keyidentifier = new DEROctetString(keyIdentifier);
165         this.certissuer = null;
166         this.certserno = null;
167     }
168
169    /**
170     * create an AuthorityKeyIdentifier with a precomupted key identifier
171     * and the GeneralNames tag and the serial number provided as well.
172     */
173    public AuthorityKeyIdentifier(
174        byte[]                  keyIdentifier,
175        GeneralNames            name,
176        BigInteger              serialNumber)
177    {
178        this.keyidentifier = new DEROctetString(keyIdentifier);
179        this.certissuer = GeneralNames.getInstance(name.toASN1Primitive());
180        this.certserno = new ASN1Integer(serialNumber);
181    }
182
183    public byte[] getKeyIdentifier()
184    {
185        if (keyidentifier != null)
186        {
187            return keyidentifier.getOctets();
188        }
189
190        return null;
191    }
192
193    public GeneralNames getAuthorityCertIssuer()
194    {
195        return certissuer;
196    }
197
198    public BigInteger getAuthorityCertSerialNumber()
199    {
200        if (certserno != null)
201        {
202            return certserno.getValue();
203        }
204
205        return null;
206    }
207
208    /**
209     * Produce an object suitable for an ASN1OutputStream.
210     */
211    public ASN1Primitive toASN1Primitive()
212    {
213        ASN1EncodableVector  v = new ASN1EncodableVector();
214
215        if (keyidentifier != null)
216        {
217            v.add(new DERTaggedObject(false, 0, keyidentifier));
218        }
219
220        if (certissuer != null)
221        {
222            v.add(new DERTaggedObject(false, 1, certissuer));
223        }
224
225        if (certserno != null)
226        {
227            v.add(new DERTaggedObject(false, 2, certserno));
228        }
229
230
231        return new DERSequence(v);
232    }
233
234    public String toString()
235    {
236        return ("AuthorityKeyIdentifier: KeyID(" + this.keyidentifier.getOctets() + ")");
237    }
238}
239