1    package org.bouncycastle.asn1.x509;
2    
3    import org.bouncycastle.crypto.Digest;
4    import org.bouncycastle.crypto.digests.SHA1Digest;
5    import org.bouncycastle.asn1.*;
6    
7    /**
8     * <pre>
9     * SubjectKeyIdentifier::= OCTET STRING
10    * </pre>
11    */
12   public class SubjectKeyIdentifier
13       implements DEREncodable
14   {
15           private byte[] keyidentifier;
16   
17       public static SubjectKeyIdentifier getInstance(
18           ASN1TaggedObject obj,
19           boolean          explicit)
20       {
21           return getInstance(ASN1OctetString.getInstance(obj, explicit));
22       }
23   
24       public static SubjectKeyIdentifier getInstance(
25           Object obj)
26       {
27           if(obj == null || obj instanceof SubjectKeyIdentifier) 
28           {
29               return (SubjectKeyIdentifier)obj;
30           }
31           
32           if(obj instanceof SubjectPublicKeyInfo) 
33           {
34               return new SubjectKeyIdentifier((SubjectPublicKeyInfo)obj);
35           }
36           
37           if(obj instanceof ASN1OctetString) 
38           {
39               return new SubjectKeyIdentifier((ASN1OctetString)obj);
40           }
41           
42           throw new IllegalArgumentException("Invalid SubjectKeyIdentifier: " + obj.getClass().getName());
43       }
44           
45       public SubjectKeyIdentifier(
46           byte[] keyid)
47       {
48           this.keyidentifier=keyid;
49       }
50   
51       public SubjectKeyIdentifier(
52           ASN1OctetString  keyid)
53       {
54                   this.keyidentifier=keyid.getOctets();
55   
56       }
57   
58           /**
59            *
60            * Calulates the keyidentifier using a SHA1 hash over the BIT STRING
61            * from SubjectPublicKeyInfo as defined in RFC2459.
62            *
63            **/
64           public SubjectKeyIdentifier(
65                   SubjectPublicKeyInfo    spki)
66           {
67                   Digest  digest = new SHA1Digest();
68                   byte[]  resBuf = new byte[digest.getDigestSize()];
69   
70                   byte[] bytes = spki.getPublicKeyData().getBytes();
71                   digest.update(bytes, 0, bytes.length);
72                   digest.doFinal(resBuf, 0);
73                   this.keyidentifier=resBuf;
74           }
75   
76       public byte[] getKeyIdentifier()
77       {
78           return keyidentifier;
79       }
80   
81        /**
82        * <pre>
83        * SubjectKeyIdentifier := OCTET STRING
84        * </pre>
85        */
86       public DERObject getDERObject()
87       {
88           return new DEROctetString(keyidentifier);
89       }
90   }
91