1 package org.bouncycastle.asn1.x509; 2 3 import org.bouncycastle.asn1.ASN1Encodable; 4 import org.bouncycastle.asn1.ASN1EncodableVector; 5 import org.bouncycastle.asn1.ASN1Sequence; 6 import org.bouncycastle.asn1.ASN1TaggedObject; 7 import org.bouncycastle.asn1.DERBitString; 8 import org.bouncycastle.asn1.DEREnumerated; 9 import org.bouncycastle.asn1.DERObject; 10 import org.bouncycastle.asn1.DERObjectIdentifier; 11 import org.bouncycastle.asn1.DERSequence; 12 13 /** 14 * ObjectDigestInfo ASN.1 structure used in v2 attribute certificates. 15 * 16 * <pre> 17 * 18 * ObjectDigestInfo ::= SEQUENCE { 19 * digestedObjectType ENUMERATED { 20 * publicKey (0), 21 * publicKeyCert (1), 22 * otherObjectTypes (2) }, 23 * -- otherObjectTypes MUST NOT 24 * -- be used in this profile 25 * otherObjectTypeID OBJECT IDENTIFIER OPTIONAL, 26 * digestAlgorithm AlgorithmIdentifier, 27 * objectDigest BIT STRING 28 * } 29 * 30 * </pre> 31 * 32 */ 33 public class ObjectDigestInfo 34 extends ASN1Encodable 35 { 36 /** 37 * The public key is hashed. 38 */ 39 public final static int publicKey = 0; 40 41 /** 42 * The public key certificate is hashed. 43 */ 44 public final static int publicKeyCert = 1; 45 46 /** 47 * An other object is hashed. 48 */ 49 public final static int otherObjectDigest = 2; 50 51 DEREnumerated digestedObjectType; 52 53 DERObjectIdentifier otherObjectTypeID; 54 55 AlgorithmIdentifier digestAlgorithm; 56 57 DERBitString objectDigest; 58 59 public static ObjectDigestInfo getInstance( 60 Object obj) 61 { 62 if (obj == null || obj instanceof ObjectDigestInfo) 63 { 64 return (ObjectDigestInfo)obj; 65 } 66 67 if (obj instanceof ASN1Sequence) 68 { 69 return new ObjectDigestInfo((ASN1Sequence)obj); 70 } 71 72 throw new IllegalArgumentException("illegal object in getInstance: " 73 + obj.getClass().getName()); 74 } 75 76 public static ObjectDigestInfo getInstance( 77 ASN1TaggedObject obj, 78 boolean explicit) 79 { 80 return getInstance(ASN1Sequence.getInstance(obj, explicit)); 81 } 82 83 /** 84 * Constructor from given details. 85 * <p> 86 * If <code>digestedObjectType</code> is not {@link #publicKeyCert} or 87 * {@link #publicKey} <code>otherObjectTypeID</code> must be given, 88 * otherwise it is ignored. 89 * 90 * @param digestedObjectType The digest object type. 91 * @param otherObjectTypeID The object type ID for 92 * <code>otherObjectDigest</code>. 93 * @param digestAlgorithm The algorithm identifier for the hash. 94 * @param objectDigest The hash value. 95 */ 96 public ObjectDigestInfo( 97 int digestedObjectType, 98 String otherObjectTypeID, 99 AlgorithmIdentifier digestAlgorithm, 100 byte[] objectDigest) 101 { 102 this.digestedObjectType = new DEREnumerated(digestedObjectType); 103 if (digestedObjectType == otherObjectDigest) 104 { 105 this.otherObjectTypeID = new DERObjectIdentifier(otherObjectTypeID); 106 } 107 108 this.digestAlgorithm = digestAlgorithm; 109 110 this.objectDigest = new DERBitString(objectDigest); 111 } 112 113 private ObjectDigestInfo( 114 ASN1Sequence seq) 115 { 116 if (seq.size() > 4 || seq.size() < 3) 117 { 118 throw new IllegalArgumentException("Bad sequence size: " 119 + seq.size()); 120 } 121 122 digestedObjectType = DEREnumerated.getInstance(seq.getObjectAt(0)); 123 124 int offset = 0; 125 126 if (seq.size() == 4) 127 { 128 otherObjectTypeID = DERObjectIdentifier.getInstance(seq.getObjectAt(1)); 129 offset++; 130 } 131 132 digestAlgorithm = AlgorithmIdentifier.getInstance(seq.getObjectAt(1 + offset)); 133 134 objectDigest = DERBitString.getInstance(seq.getObjectAt(2 + offset)); 135 } 136 137 public DEREnumerated getDigestedObjectType() 138 { 139 return digestedObjectType; 140 } 141 142 public DERObjectIdentifier getOtherObjectTypeID() 143 { 144 return otherObjectTypeID; 145 } 146 147 public AlgorithmIdentifier getDigestAlgorithm() 148 { 149 return digestAlgorithm; 150 } 151 152 public DERBitString getObjectDigest() 153 { 154 return objectDigest; 155 } 156 157 /** 158 * Produce an object suitable for an ASN1OutputStream. 159 * 160 * <pre> 161 * 162 * ObjectDigestInfo ::= SEQUENCE { 163 * digestedObjectType ENUMERATED { 164 * publicKey (0), 165 * publicKeyCert (1), 166 * otherObjectTypes (2) }, 167 * -- otherObjectTypes MUST NOT 168 * -- be used in this profile 169 * otherObjectTypeID OBJECT IDENTIFIER OPTIONAL, 170 * digestAlgorithm AlgorithmIdentifier, 171 * objectDigest BIT STRING 172 * } 173 * 174 * </pre> 175 */ 176 public DERObject toASN1Object() 177 { 178 ASN1EncodableVector v = new ASN1EncodableVector(); 179 180 v.add(digestedObjectType); 181 182 if (otherObjectTypeID != null) 183 { 184 v.add(otherObjectTypeID); 185 } 186 187 v.add(digestAlgorithm); 188 v.add(objectDigest); 189 190 return new DERSequence(v); 191 } 192 } 193