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 * @deprecated create the extension using org.bouncycastle.cert.X509ExtensionUtils 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 * @deprecated create the extension using org.bouncycastle.cert.X509ExtensionUtils 126 */ 127 public AuthorityKeyIdentifier( 128 SubjectPublicKeyInfo spki, 129 GeneralNames name, 130 BigInteger serialNumber) 131 { 132 // BEGIN android-changed 133 Digest digest = AndroidDigestFactory.getSHA1(); 134 // END android-changed 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