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 precomputed 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 precomputed 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