1 package org.bouncycastle.asn1.tsp; 2 3 import java.io.IOException; 4 import java.util.Enumeration; 5 6 import org.bouncycastle.asn1.ASN1Encodable; 7 import org.bouncycastle.asn1.ASN1InputStream; 8 import org.bouncycastle.asn1.ASN1OctetString; 9 import org.bouncycastle.asn1.ASN1Sequence; 10 import org.bouncycastle.asn1.ASN1TaggedObject; 11 import org.bouncycastle.asn1.DERBoolean; 12 import org.bouncycastle.asn1.DEREncodableVector; 13 import org.bouncycastle.asn1.DERGeneralizedTime; 14 import org.bouncycastle.asn1.DERInteger; 15 import org.bouncycastle.asn1.DERObject; 16 import org.bouncycastle.asn1.DERObjectIdentifier; 17 import org.bouncycastle.asn1.DERSequence; 18 import org.bouncycastle.asn1.DERTaggedObject; 19 import org.bouncycastle.asn1.x509.GeneralName; 20 import org.bouncycastle.asn1.x509.X509Extensions; 21 22 public class TSTInfo 23 extends ASN1Encodable 24 { 25 DERInteger version; 26 27 DERObjectIdentifier tsaPolicyId; 28 29 MessageImprint messageImprint; 30 31 DERInteger serialNumber; 32 33 DERGeneralizedTime genTime; 34 35 Accuracy accuracy; 36 37 DERBoolean ordering; 38 39 DERInteger nonce; 40 41 GeneralName tsa; 42 43 X509Extensions extensions; 44 45 public static TSTInfo getInstance(Object o) 46 { 47 if (o == null || o instanceof TSTInfo) 48 { 49 return (TSTInfo) o; 50 } 51 else if (o instanceof ASN1Sequence) 52 { 53 return new TSTInfo((ASN1Sequence) o); 54 } 55 else if (o instanceof ASN1OctetString) 56 { 57 try 58 { 59 return getInstance(new ASN1InputStream(((ASN1OctetString)o).getOctets()).readObject()); 60 } 61 catch (IOException ioEx) 62 { 63 throw new IllegalArgumentException( 64 "Bad object format in 'TSTInfo' factory."); 65 } 66 } 67 68 throw new IllegalArgumentException( 69 "Unknown object in 'TSTInfo' factory : " 70 + o.getClass().getName() + "."); 71 } 72 73 public TSTInfo(ASN1Sequence seq) 74 { 75 Enumeration e = seq.getObjects(); 76 77 // version 78 version = DERInteger.getInstance(e.nextElement()); 79 80 // tsaPolicy 81 tsaPolicyId = DERObjectIdentifier.getInstance(e.nextElement()); 82 83 // messageImprint 84 messageImprint = MessageImprint.getInstance(e.nextElement()); 85 86 // serialNumber 87 serialNumber = DERInteger.getInstance(e.nextElement()); 88 89 // genTime 90 genTime = DERGeneralizedTime.getInstance(e.nextElement()); 91 92 // default for ordering 93 // BEGIN android-changed 94 ordering = DERBoolean.FALSE; 95 // END android-changed 96 97 while (e.hasMoreElements()) 98 { 99 DERObject o = (DERObject) e.nextElement(); 100 101 if (o instanceof ASN1TaggedObject) 102 { 103 DERTaggedObject tagged = (DERTaggedObject) o; 104 105 switch (tagged.getTagNo()) 106 { 107 case 0: 108 tsa = GeneralName.getInstance(tagged, true); 109 break; 110 case 1: 111 extensions = X509Extensions.getInstance(tagged, false); 112 break; 113 default: 114 throw new IllegalArgumentException("Unknown tag value " + tagged.getTagNo()); 115 } 116 } 117 else if (o instanceof DERSequence) 118 { 119 accuracy = Accuracy.getInstance(o); 120 } 121 else if (o instanceof DERBoolean) 122 { 123 ordering = DERBoolean.getInstance(o); 124 } 125 else if (o instanceof DERInteger) 126 { 127 nonce = DERInteger.getInstance(o); 128 } 129 130 } 131 } 132 133 public TSTInfo(DERObjectIdentifier tsaPolicyId, MessageImprint messageImprint, 134 DERInteger serialNumber, DERGeneralizedTime genTime, 135 Accuracy accuracy, DERBoolean ordering, DERInteger nonce, 136 GeneralName tsa, X509Extensions extensions) 137 { 138 version = new DERInteger(1); 139 this.tsaPolicyId = tsaPolicyId; 140 this.messageImprint = messageImprint; 141 this.serialNumber = serialNumber; 142 this.genTime = genTime; 143 144 this.accuracy = accuracy; 145 this.ordering = ordering; 146 this.nonce = nonce; 147 this.tsa = tsa; 148 this.extensions = extensions; 149 } 150 151 public MessageImprint getMessageImprint() 152 { 153 return messageImprint; 154 } 155 156 public DERObjectIdentifier getPolicy() 157 { 158 return tsaPolicyId; 159 } 160 161 public DERInteger getSerialNumber() 162 { 163 return serialNumber; 164 } 165 166 public Accuracy getAccuracy() 167 { 168 return accuracy; 169 } 170 171 public DERGeneralizedTime getGenTime() 172 { 173 return genTime; 174 } 175 176 public DERBoolean getOrdering() 177 { 178 return ordering; 179 } 180 181 public DERInteger getNonce() 182 { 183 return nonce; 184 } 185 186 public GeneralName getTsa() 187 { 188 return tsa; 189 } 190 191 public X509Extensions getExtensions() 192 { 193 return extensions; 194 } 195 196 /** 197 * <pre> 198 * 199 * TSTInfo ::= SEQUENCE { 200 * version INTEGER { v1(1) }, 201 * policy TSAPolicyId, 202 * messageImprint MessageImprint, 203 * -- MUST have the same value as the similar field in 204 * -- TimeStampReq 205 * serialNumber INTEGER, 206 * -- Time-Stamping users MUST be ready to accommodate integers 207 * -- up to 160 bits. 208 * genTime GeneralizedTime, 209 * accuracy Accuracy OPTIONAL, 210 * ordering BOOLEAN DEFAULT FALSE, 211 * nonce INTEGER OPTIONAL, 212 * -- MUST be present if the similar field was present 213 * -- in TimeStampReq. In that case it MUST have the same value. 214 * tsa [0] GeneralName OPTIONAL, 215 * extensions [1] IMPLICIT Extensions OPTIONAL } 216 * 217 * </pre> 218 */ 219 public DERObject toASN1Object() 220 { 221 DEREncodableVector seq = new DEREncodableVector(); 222 seq.add(version); 223 224 seq.add(tsaPolicyId); 225 seq.add(messageImprint); 226 seq.add(serialNumber); 227 seq.add(genTime); 228 229 if (accuracy != null) 230 { 231 seq.add(accuracy); 232 } 233 234 if (ordering != null && ordering.isTrue()) 235 { 236 seq.add(ordering); 237 } 238 239 if (nonce != null) 240 { 241 seq.add(nonce); 242 } 243 244 if (tsa != null) 245 { 246 seq.add(new DERTaggedObject(true, 0, tsa)); 247 } 248 249 if (extensions != null) 250 { 251 seq.add(new DERTaggedObject(false, 1, extensions)); 252 } 253 254 return new DERSequence(seq); 255 } 256 } 257