Home | History | Annotate | Download | only in x509
      1 package org.bouncycastle.asn1.x509;
      2 
      3 import java.math.BigInteger;
      4 import java.util.Enumeration;
      5 
      6 import org.bouncycastle.asn1.ASN1EncodableVector;
      7 import org.bouncycastle.asn1.ASN1Integer;
      8 import org.bouncycastle.asn1.ASN1Object;
      9 import org.bouncycastle.asn1.ASN1OctetString;
     10 import org.bouncycastle.asn1.ASN1Primitive;
     11 import org.bouncycastle.asn1.ASN1Sequence;
     12 import org.bouncycastle.asn1.ASN1TaggedObject;
     13 import org.bouncycastle.asn1.DEROctetString;
     14 import org.bouncycastle.asn1.DERSequence;
     15 import org.bouncycastle.asn1.DERTaggedObject;
     16 import org.bouncycastle.crypto.Digest;
     17 // Android-changed: Use Android digests
     18 // import org.bouncycastle.crypto.digests.SHA1Digest;
     19 import org.bouncycastle.crypto.digests.AndroidDigestFactory;
     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  */
     35 public 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      * @deprecated create the extension using org.bouncycastle.cert.X509ExtensionUtils
    107      **/
    108     public AuthorityKeyIdentifier(
    109         SubjectPublicKeyInfo    spki)
    110     {
    111         // Android-changed: Use Android digests
    112         // Digest  digest = new SHA1Digest();
    113         Digest  digest = AndroidDigestFactory.getSHA1();
    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      * @deprecated create the extension using org.bouncycastle.cert.X509ExtensionUtils
    126      */
    127     public AuthorityKeyIdentifier(
    128         SubjectPublicKeyInfo    spki,
    129         GeneralNames            name,
    130         BigInteger              serialNumber)
    131     {
    132         // Android-changed: Use Android digests
    133         // Digest  digest = new SHA1Digest();
    134         Digest  digest = AndroidDigestFactory.getSHA1();
    135         byte[]  resBuf = new byte[digest.getDigestSize()];
    136 
    137         byte[] bytes = spki.getPublicKeyData().getBytes();
    138         digest.update(bytes, 0, bytes.length);
    139         digest.doFinal(resBuf, 0);
    140 
    141         this.keyidentifier = new DEROctetString(resBuf);
    142         this.certissuer = GeneralNames.getInstance(name.toASN1Primitive());
    143         this.certserno = new ASN1Integer(serialNumber);
    144     }
    145 
    146     /**
    147      * create an AuthorityKeyIdentifier with the GeneralNames tag and
    148      * the serial number provided.
    149      */
    150     public AuthorityKeyIdentifier(
    151         GeneralNames            name,
    152         BigInteger              serialNumber)
    153     {
    154         this((byte[])null, name, serialNumber);
    155     }
    156 
    157     /**
    158       * create an AuthorityKeyIdentifier with a precomputed key identifier
    159       */
    160      public AuthorityKeyIdentifier(
    161          byte[]                  keyIdentifier)
    162      {
    163          this(keyIdentifier, null, null);
    164      }
    165 
    166     /**
    167      * create an AuthorityKeyIdentifier with a precomputed key identifier
    168      * and the GeneralNames tag and the serial number provided as well.
    169      */
    170     public AuthorityKeyIdentifier(
    171         byte[]                  keyIdentifier,
    172         GeneralNames            name,
    173         BigInteger              serialNumber)
    174     {
    175         this.keyidentifier = (keyIdentifier != null) ? new DEROctetString(keyIdentifier) : null;
    176         this.certissuer = name;
    177         this.certserno = (serialNumber != null) ? new ASN1Integer(serialNumber) : null;
    178     }
    179 
    180     public byte[] getKeyIdentifier()
    181     {
    182         if (keyidentifier != null)
    183         {
    184             return keyidentifier.getOctets();
    185         }
    186 
    187         return null;
    188     }
    189 
    190     public GeneralNames getAuthorityCertIssuer()
    191     {
    192         return certissuer;
    193     }
    194 
    195     public BigInteger getAuthorityCertSerialNumber()
    196     {
    197         if (certserno != null)
    198         {
    199             return certserno.getValue();
    200         }
    201 
    202         return null;
    203     }
    204 
    205     /**
    206      * Produce an object suitable for an ASN1OutputStream.
    207      */
    208     public ASN1Primitive toASN1Primitive()
    209     {
    210         ASN1EncodableVector  v = new ASN1EncodableVector();
    211 
    212         if (keyidentifier != null)
    213         {
    214             v.add(new DERTaggedObject(false, 0, keyidentifier));
    215         }
    216 
    217         if (certissuer != null)
    218         {
    219             v.add(new DERTaggedObject(false, 1, certissuer));
    220         }
    221 
    222         if (certserno != null)
    223         {
    224             v.add(new DERTaggedObject(false, 2, certserno));
    225         }
    226 
    227 
    228         return new DERSequence(v);
    229     }
    230 
    231     public String toString()
    232     {
    233         return ("AuthorityKeyIdentifier: KeyID(" + this.keyidentifier.getOctets() + ")");
    234     }
    235 }
    236