1package org.bouncycastle.asn1.x509; 2 3import org.bouncycastle.asn1.ASN1Encodable; 4import org.bouncycastle.asn1.ASN1EncodableVector; 5import org.bouncycastle.asn1.ASN1OctetString; 6import org.bouncycastle.asn1.ASN1Sequence; 7import org.bouncycastle.asn1.ASN1TaggedObject; 8import org.bouncycastle.asn1.DERInteger; 9import org.bouncycastle.asn1.DERObject; 10import org.bouncycastle.asn1.DEROctetString; 11import org.bouncycastle.asn1.DERSequence; 12import org.bouncycastle.asn1.DERTaggedObject; 13import org.bouncycastle.crypto.Digest; 14import org.bouncycastle.crypto.digests.SHA1Digest; 15 16import java.math.BigInteger; 17import java.util.Enumeration; 18 19/** 20 * The AuthorityKeyIdentifier object. 21 * <pre> 22 * id-ce-authorityKeyIdentifier OBJECT IDENTIFIER ::= { id-ce 35 } 23 * 24 * AuthorityKeyIdentifier ::= SEQUENCE { 25 * keyIdentifier [0] IMPLICIT KeyIdentifier OPTIONAL, 26 * authorityCertIssuer [1] IMPLICIT GeneralNames OPTIONAL, 27 * authorityCertSerialNumber [2] IMPLICIT CertificateSerialNumber OPTIONAL } 28 * 29 * KeyIdentifier ::= OCTET STRING 30 * </pre> 31 * 32 */ 33public class AuthorityKeyIdentifier 34 extends ASN1Encodable 35{ 36 ASN1OctetString keyidentifier=null; 37 GeneralNames certissuer=null; 38 DERInteger certserno=null; 39 40 public static AuthorityKeyIdentifier getInstance( 41 ASN1TaggedObject obj, 42 boolean explicit) 43 { 44 return getInstance(ASN1Sequence.getInstance(obj, explicit)); 45 } 46 47 public static AuthorityKeyIdentifier getInstance( 48 Object obj) 49 { 50 if (obj instanceof AuthorityKeyIdentifier) 51 { 52 return (AuthorityKeyIdentifier)obj; 53 } 54 if (obj instanceof ASN1Sequence) 55 { 56 return new AuthorityKeyIdentifier((ASN1Sequence)obj); 57 } 58 if (obj instanceof X509Extension) 59 { 60 return getInstance(X509Extension.convertValueToObject((X509Extension)obj)); 61 } 62 63 throw new IllegalArgumentException("unknown object in factory: " + obj.getClass().getName()); 64 } 65 66 public AuthorityKeyIdentifier( 67 ASN1Sequence seq) 68 { 69 Enumeration e = seq.getObjects(); 70 71 while (e.hasMoreElements()) 72 { 73 ASN1TaggedObject o = DERTaggedObject.getInstance(e.nextElement()); 74 75 switch (o.getTagNo()) 76 { 77 case 0: 78 this.keyidentifier = ASN1OctetString.getInstance(o, false); 79 break; 80 case 1: 81 this.certissuer = GeneralNames.getInstance(o, false); 82 break; 83 case 2: 84 this.certserno = DERInteger.getInstance(o, false); 85 break; 86 default: 87 throw new IllegalArgumentException("illegal tag"); 88 } 89 } 90 } 91 92 /** 93 * 94 * Calulates the keyidentifier using a SHA1 hash over the BIT STRING 95 * from SubjectPublicKeyInfo as defined in RFC2459. 96 * 97 * Example of making a AuthorityKeyIdentifier: 98 * <pre> 99 * SubjectPublicKeyInfo apki = new SubjectPublicKeyInfo((ASN1Sequence)new ASN1InputStream( 100 * publicKey.getEncoded()).readObject()); 101 * AuthorityKeyIdentifier aki = new AuthorityKeyIdentifier(apki); 102 * </pre> 103 * 104 **/ 105 public AuthorityKeyIdentifier( 106 SubjectPublicKeyInfo spki) 107 { 108 Digest digest = new SHA1Digest(); 109 byte[] resBuf = new byte[digest.getDigestSize()]; 110 111 byte[] bytes = spki.getPublicKeyData().getBytes(); 112 digest.update(bytes, 0, bytes.length); 113 digest.doFinal(resBuf, 0); 114 this.keyidentifier = new DEROctetString(resBuf); 115 } 116 117 /** 118 * create an AuthorityKeyIdentifier with the GeneralNames tag and 119 * the serial number provided as well. 120 */ 121 public AuthorityKeyIdentifier( 122 SubjectPublicKeyInfo spki, 123 GeneralNames name, 124 BigInteger serialNumber) 125 { 126 Digest digest = new SHA1Digest(); 127 byte[] resBuf = new byte[digest.getDigestSize()]; 128 129 byte[] bytes = spki.getPublicKeyData().getBytes(); 130 digest.update(bytes, 0, bytes.length); 131 digest.doFinal(resBuf, 0); 132 133 this.keyidentifier = new DEROctetString(resBuf); 134 this.certissuer = GeneralNames.getInstance(name.toASN1Object()); 135 this.certserno = new DERInteger(serialNumber); 136 } 137 138 /** 139 * create an AuthorityKeyIdentifier with the GeneralNames tag and 140 * the serial number provided. 141 */ 142 public AuthorityKeyIdentifier( 143 GeneralNames name, 144 BigInteger serialNumber) 145 { 146 this.keyidentifier = null; 147 this.certissuer = GeneralNames.getInstance(name.toASN1Object()); 148 this.certserno = new DERInteger(serialNumber); 149 } 150 151 /** 152 * create an AuthorityKeyIdentifier with a precomupted key identifier 153 */ 154 public AuthorityKeyIdentifier( 155 byte[] keyIdentifier) 156 { 157 this.keyidentifier = new DEROctetString(keyIdentifier); 158 this.certissuer = null; 159 this.certserno = null; 160 } 161 162 /** 163 * create an AuthorityKeyIdentifier with a precomupted key identifier 164 * and the GeneralNames tag and the serial number provided as well. 165 */ 166 public AuthorityKeyIdentifier( 167 byte[] keyIdentifier, 168 GeneralNames name, 169 BigInteger serialNumber) 170 { 171 this.keyidentifier = new DEROctetString(keyIdentifier); 172 this.certissuer = GeneralNames.getInstance(name.toASN1Object()); 173 this.certserno = new DERInteger(serialNumber); 174 } 175 176 public byte[] getKeyIdentifier() 177 { 178 if (keyidentifier != null) 179 { 180 return keyidentifier.getOctets(); 181 } 182 183 return null; 184 } 185 186 public GeneralNames getAuthorityCertIssuer() 187 { 188 return certissuer; 189 } 190 191 public BigInteger getAuthorityCertSerialNumber() 192 { 193 if (certserno != null) 194 { 195 return certserno.getValue(); 196 } 197 198 return null; 199 } 200 201 /** 202 * Produce an object suitable for an ASN1OutputStream. 203 */ 204 public DERObject toASN1Object() 205 { 206 ASN1EncodableVector v = new ASN1EncodableVector(); 207 208 if (keyidentifier != null) 209 { 210 v.add(new DERTaggedObject(false, 0, keyidentifier)); 211 } 212 213 if (certissuer != null) 214 { 215 v.add(new DERTaggedObject(false, 1, certissuer)); 216 } 217 218 if (certserno != null) 219 { 220 v.add(new DERTaggedObject(false, 2, certserno)); 221 } 222 223 224 return new DERSequence(v); 225 } 226 227 public String toString() 228 { 229 return ("AuthorityKeyIdentifier: KeyID(" + this.keyidentifier.getOctets() + ")"); 230 } 231} 232