SubjectKeyIdentifier.java revision e6bf3e8dfa2804891a82075cb469b736321b4827
1package org.bouncycastle.asn1.x509; 2 3import org.bouncycastle.asn1.ASN1Object; 4import org.bouncycastle.asn1.ASN1OctetString; 5import org.bouncycastle.asn1.ASN1Primitive; 6import org.bouncycastle.asn1.ASN1TaggedObject; 7import org.bouncycastle.asn1.DEROctetString; 8import org.bouncycastle.crypto.Digest; 9// BEGIN android-changed 10import org.bouncycastle.crypto.digests.AndroidDigestFactory; 11// END android-changed 12 13/** 14 * The SubjectKeyIdentifier object. 15 * <pre> 16 * SubjectKeyIdentifier::= OCTET STRING 17 * </pre> 18 */ 19public 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 SubjectKeyIdentifier( 47 byte[] keyid) 48 { 49 this.keyidentifier = keyid; 50 } 51 52 protected SubjectKeyIdentifier( 53 ASN1OctetString keyid) 54 { 55 this.keyidentifier = keyid.getOctets(); 56 } 57 58 public byte[] getKeyIdentifier() 59 { 60 return keyidentifier; 61 } 62 63 public ASN1Primitive toASN1Primitive() 64 { 65 return new DEROctetString(keyidentifier); 66 } 67 68 69 /** 70 * Calculates the keyidentifier using a SHA1 hash over the BIT STRING 71 * from SubjectPublicKeyInfo as defined in RFC3280. 72 * 73 * @param spki the subject public key info. 74 * @deprecated 75 */ 76 public SubjectKeyIdentifier( 77 SubjectPublicKeyInfo spki) 78 { 79 this.keyidentifier = getDigest(spki); 80 } 81 82 /** 83 * Return a RFC 3280 type 1 key identifier. As in: 84 * <pre> 85 * (1) The keyIdentifier is composed of the 160-bit SHA-1 hash of the 86 * value of the BIT STRING subjectPublicKey (excluding the tag, 87 * length, and number of unused bits). 88 * </pre> 89 * @param keyInfo the key info object containing the subjectPublicKey field. 90 * @return the key identifier. 91 * @deprecated use org.bouncycastle.cert.X509ExtensionUtils.createSubjectKeyIdentifier 92 */ 93 public static SubjectKeyIdentifier createSHA1KeyIdentifier(SubjectPublicKeyInfo keyInfo) 94 { 95 return new SubjectKeyIdentifier(keyInfo); 96 } 97 98 /** 99 * Return a RFC 3280 type 2 key identifier. As in: 100 * <pre> 101 * (2) The keyIdentifier is composed of a four bit type field with 102 * the value 0100 followed by the least significant 60 bits of the 103 * SHA-1 hash of the value of the BIT STRING subjectPublicKey. 104 * </pre> 105 * @param keyInfo the key info object containing the subjectPublicKey field. 106 * @return the key identifier. 107 * @deprecated use org.bouncycastle.cert.X509ExtensionUtils.createTruncatedSubjectKeyIdentifier 108 */ 109 public static SubjectKeyIdentifier createTruncatedSHA1KeyIdentifier(SubjectPublicKeyInfo keyInfo) 110 { 111 byte[] dig = getDigest(keyInfo); 112 byte[] id = new byte[8]; 113 114 System.arraycopy(dig, dig.length - 8, id, 0, id.length); 115 116 id[0] &= 0x0f; 117 id[0] |= 0x40; 118 119 return new SubjectKeyIdentifier(id); 120 } 121 122 private static byte[] getDigest(SubjectPublicKeyInfo spki) 123 { 124 // BEGIN android-changed 125 Digest digest = AndroidDigestFactory.getSHA1(); 126 // END android-changed 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 return resBuf; 133 } 134} 135