Home | History | Annotate | Download | only in x509
      1 package org.bouncycastle.asn1.x509;
      2 
      3 import org.bouncycastle.asn1.ASN1Object;
      4 import org.bouncycastle.asn1.ASN1OctetString;
      5 import org.bouncycastle.asn1.ASN1Primitive;
      6 import org.bouncycastle.asn1.ASN1TaggedObject;
      7 import org.bouncycastle.asn1.DEROctetString;
      8 import org.bouncycastle.crypto.Digest;
      9 // BEGIN android-changed
     10 import org.bouncycastle.crypto.digests.AndroidDigestFactory;
     11 // END android-changed
     12 
     13 /**
     14  * The SubjectKeyIdentifier object.
     15  * <pre>
     16  * SubjectKeyIdentifier::= OCTET STRING
     17  * </pre>
     18  */
     19 public class SubjectKeyIdentifier
     20     extends ASN1Object
     21 {
     22     private byte[] keyidentifier;
     23 
     24     public static SubjectKeyIdentifier getInstance(
     25         ASN1TaggedObject obj,
     26         boolean          explicit)
     27     {
     28         return getInstance(ASN1OctetString.getInstance(obj, explicit));
     29     }
     30 
     31     public static SubjectKeyIdentifier getInstance(
     32         Object obj)
     33     {
     34         if (obj instanceof SubjectKeyIdentifier)
     35         {
     36             return (SubjectKeyIdentifier)obj;
     37         }
     38         else if (obj != null)
     39         {
     40             return new SubjectKeyIdentifier(ASN1OctetString.getInstance(obj));
     41         }
     42 
     43         return null;
     44     }
     45 
     46     public static SubjectKeyIdentifier fromExtensions(Extensions extensions)
     47     {
     48         return SubjectKeyIdentifier.getInstance(extensions.getExtensionParsedValue(Extension.subjectKeyIdentifier));
     49     }
     50 
     51     public SubjectKeyIdentifier(
     52         byte[] keyid)
     53     {
     54         this.keyidentifier = keyid;
     55     }
     56 
     57     protected SubjectKeyIdentifier(
     58         ASN1OctetString keyid)
     59     {
     60         this.keyidentifier = keyid.getOctets();
     61     }
     62 
     63     public byte[] getKeyIdentifier()
     64     {
     65         return keyidentifier;
     66     }
     67 
     68     public ASN1Primitive toASN1Primitive()
     69     {
     70         return new DEROctetString(keyidentifier);
     71     }
     72 
     73 
     74     /**
     75      * Calculates the keyidentifier using a SHA1 hash over the BIT STRING
     76      * from SubjectPublicKeyInfo as defined in RFC3280.
     77      *
     78      * @param spki the subject public key info.
     79      * @deprecated
     80      */
     81     public SubjectKeyIdentifier(
     82         SubjectPublicKeyInfo    spki)
     83     {
     84         this.keyidentifier = getDigest(spki);
     85     }
     86 
     87     /**
     88      * Return a RFC 3280 type 1 key identifier. As in:
     89      * <pre>
     90      * (1) The keyIdentifier is composed of the 160-bit SHA-1 hash of the
     91      * value of the BIT STRING subjectPublicKey (excluding the tag,
     92      * length, and number of unused bits).
     93      * </pre>
     94      * @param keyInfo the key info object containing the subjectPublicKey field.
     95      * @return the key identifier.
     96      * @deprecated use org.bouncycastle.cert.X509ExtensionUtils.createSubjectKeyIdentifier
     97      */
     98     public static SubjectKeyIdentifier createSHA1KeyIdentifier(SubjectPublicKeyInfo keyInfo)
     99     {
    100         return new SubjectKeyIdentifier(keyInfo);
    101     }
    102 
    103     /**
    104      * Return a RFC 3280 type 2 key identifier. As in:
    105      * <pre>
    106      * (2) The keyIdentifier is composed of a four bit type field with
    107      * the value 0100 followed by the least significant 60 bits of the
    108      * SHA-1 hash of the value of the BIT STRING subjectPublicKey.
    109      * </pre>
    110      * @param keyInfo the key info object containing the subjectPublicKey field.
    111      * @return the key identifier.
    112      * @deprecated use org.bouncycastle.cert.X509ExtensionUtils.createTruncatedSubjectKeyIdentifier
    113      */
    114     public static SubjectKeyIdentifier createTruncatedSHA1KeyIdentifier(SubjectPublicKeyInfo keyInfo)
    115     {
    116         byte[] dig = getDigest(keyInfo);
    117         byte[] id = new byte[8];
    118 
    119         System.arraycopy(dig, dig.length - 8, id, 0, id.length);
    120 
    121         id[0] &= 0x0f;
    122         id[0] |= 0x40;
    123 
    124         return new SubjectKeyIdentifier(id);
    125     }
    126 
    127     private static byte[] getDigest(SubjectPublicKeyInfo spki)
    128     {
    129         // BEGIN android-changed
    130         Digest digest = AndroidDigestFactory.getSHA1();
    131         // END android-changed
    132         byte[]  resBuf = new byte[digest.getDigestSize()];
    133 
    134         byte[] bytes = spki.getPublicKeyData().getBytes();
    135         digest.update(bytes, 0, bytes.length);
    136         digest.doFinal(resBuf, 0);
    137         return resBuf;
    138     }
    139 }
    140