TBSCertList.java revision e6bf3e8dfa2804891a82075cb469b736321b4827
19682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hallpackage org.bouncycastle.asn1.x509; 29682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall 39682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hallimport java.util.Enumeration; 49682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall 59682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hallimport org.bouncycastle.asn1.ASN1EncodableVector; 69682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hallimport org.bouncycastle.asn1.ASN1Integer; 79682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hallimport org.bouncycastle.asn1.ASN1Object; 89682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hallimport org.bouncycastle.asn1.ASN1Primitive; 99682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hallimport org.bouncycastle.asn1.ASN1Sequence; 109682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hallimport org.bouncycastle.asn1.ASN1TaggedObject; 119682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hallimport org.bouncycastle.asn1.DERGeneralizedTime; 129682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hallimport org.bouncycastle.asn1.DERSequence; 139682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hallimport org.bouncycastle.asn1.DERTaggedObject; 149682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hallimport org.bouncycastle.asn1.DERUTCTime; 159682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hallimport org.bouncycastle.asn1.x500.X500Name; 169682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall 179682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall/** 189682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall * PKIX RFC-2459 - TBSCertList object. 199682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall * <pre> 209682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall * TBSCertList ::= SEQUENCE { 219682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall * version Version OPTIONAL, 229682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall * -- if present, shall be v2 239682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall * signature AlgorithmIdentifier, 249682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall * issuer Name, 259682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall * thisUpdate Time, 269682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall * nextUpdate Time OPTIONAL, 279682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall * revokedCertificates SEQUENCE OF SEQUENCE { 289682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall * userCertificate CertificateSerialNumber, 299682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall * revocationDate Time, 309682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall * crlEntryExtensions Extensions OPTIONAL 319682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall * -- if present, shall be v2 329682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall * } OPTIONAL, 339682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall * crlExtensions [0] EXPLICIT Extensions OPTIONAL 349682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall * -- if present, shall be v2 359682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall * } 369682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall * </pre> 379682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall */ 389682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hallpublic class TBSCertList 399682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall extends ASN1Object 409682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall{ 419682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall public static class CRLEntry 429682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall extends ASN1Object 439682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall { 449682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall ASN1Sequence seq; 459682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall 469682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall Extensions crlEntryExtensions; 479682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall 489682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall private CRLEntry( 499682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall ASN1Sequence seq) 509682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall { 519682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall if (seq.size() < 2 || seq.size() > 3) 529682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall { 539682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall throw new IllegalArgumentException("Bad sequence size: " + seq.size()); 549682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall } 559682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall 569682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall this.seq = seq; 579682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall } 589682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall 599682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall public static CRLEntry getInstance(Object o) 609682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall { 619682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall if (o instanceof CRLEntry) 629682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall { 639682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall return ((CRLEntry)o); 649682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall } 659682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall else if (o != null) 669682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall { 679682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall return new CRLEntry(ASN1Sequence.getInstance(o)); 689682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall } 699682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall 709682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall return null; 719682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall } 729682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall 739682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall public ASN1Integer getUserCertificate() 74 { 75 return ASN1Integer.getInstance(seq.getObjectAt(0)); 76 } 77 78 public Time getRevocationDate() 79 { 80 return Time.getInstance(seq.getObjectAt(1)); 81 } 82 83 public Extensions getExtensions() 84 { 85 if (crlEntryExtensions == null && seq.size() == 3) 86 { 87 crlEntryExtensions = Extensions.getInstance(seq.getObjectAt(2)); 88 } 89 90 return crlEntryExtensions; 91 } 92 93 public ASN1Primitive toASN1Primitive() 94 { 95 return seq; 96 } 97 98 public boolean hasExtensions() 99 { 100 return seq.size() == 3; 101 } 102 } 103 104 private class RevokedCertificatesEnumeration 105 implements Enumeration 106 { 107 private final Enumeration en; 108 109 RevokedCertificatesEnumeration(Enumeration en) 110 { 111 this.en = en; 112 } 113 114 public boolean hasMoreElements() 115 { 116 return en.hasMoreElements(); 117 } 118 119 public Object nextElement() 120 { 121 return CRLEntry.getInstance(en.nextElement()); 122 } 123 } 124 125 private class EmptyEnumeration 126 implements Enumeration 127 { 128 public boolean hasMoreElements() 129 { 130 return false; 131 } 132 133 public Object nextElement() 134 { 135 return null; // TODO: check exception handling 136 } 137 } 138 139 ASN1Integer version; 140 AlgorithmIdentifier signature; 141 X500Name issuer; 142 Time thisUpdate; 143 Time nextUpdate; 144 ASN1Sequence revokedCertificates; 145 Extensions crlExtensions; 146 147 public static TBSCertList getInstance( 148 ASN1TaggedObject obj, 149 boolean explicit) 150 { 151 return getInstance(ASN1Sequence.getInstance(obj, explicit)); 152 } 153 154 public static TBSCertList getInstance( 155 Object obj) 156 { 157 if (obj instanceof TBSCertList) 158 { 159 return (TBSCertList)obj; 160 } 161 else if (obj != null) 162 { 163 return new TBSCertList(ASN1Sequence.getInstance(obj)); 164 } 165 166 return null; 167 } 168 169 public TBSCertList( 170 ASN1Sequence seq) 171 { 172 if (seq.size() < 3 || seq.size() > 7) 173 { 174 throw new IllegalArgumentException("Bad sequence size: " + seq.size()); 175 } 176 177 int seqPos = 0; 178 179 if (seq.getObjectAt(seqPos) instanceof ASN1Integer) 180 { 181 version = ASN1Integer.getInstance(seq.getObjectAt(seqPos++)); 182 } 183 else 184 { 185 version = null; // version is optional 186 } 187 188 signature = AlgorithmIdentifier.getInstance(seq.getObjectAt(seqPos++)); 189 issuer = X500Name.getInstance(seq.getObjectAt(seqPos++)); 190 thisUpdate = Time.getInstance(seq.getObjectAt(seqPos++)); 191 192 if (seqPos < seq.size() 193 && (seq.getObjectAt(seqPos) instanceof DERUTCTime 194 || seq.getObjectAt(seqPos) instanceof DERGeneralizedTime 195 || seq.getObjectAt(seqPos) instanceof Time)) 196 { 197 nextUpdate = Time.getInstance(seq.getObjectAt(seqPos++)); 198 } 199 200 if (seqPos < seq.size() 201 && !(seq.getObjectAt(seqPos) instanceof DERTaggedObject)) 202 { 203 revokedCertificates = ASN1Sequence.getInstance(seq.getObjectAt(seqPos++)); 204 } 205 206 if (seqPos < seq.size() 207 && seq.getObjectAt(seqPos) instanceof DERTaggedObject) 208 { 209 crlExtensions = Extensions.getInstance(ASN1Sequence.getInstance((ASN1TaggedObject)seq.getObjectAt(seqPos), true)); 210 } 211 } 212 213 public int getVersionNumber() 214 { 215 if (version == null) 216 { 217 return 1; 218 } 219 return version.getValue().intValue() + 1; 220 } 221 222 public ASN1Integer getVersion() 223 { 224 return version; 225 } 226 227 public AlgorithmIdentifier getSignature() 228 { 229 return signature; 230 } 231 232 public X500Name getIssuer() 233 { 234 return issuer; 235 } 236 237 public Time getThisUpdate() 238 { 239 return thisUpdate; 240 } 241 242 public Time getNextUpdate() 243 { 244 return nextUpdate; 245 } 246 247 public CRLEntry[] getRevokedCertificates() 248 { 249 if (revokedCertificates == null) 250 { 251 return new CRLEntry[0]; 252 } 253 254 CRLEntry[] entries = new CRLEntry[revokedCertificates.size()]; 255 256 for (int i = 0; i < entries.length; i++) 257 { 258 entries[i] = CRLEntry.getInstance(revokedCertificates.getObjectAt(i)); 259 } 260 261 return entries; 262 } 263 264 public Enumeration getRevokedCertificateEnumeration() 265 { 266 if (revokedCertificates == null) 267 { 268 return new EmptyEnumeration(); 269 } 270 271 return new RevokedCertificatesEnumeration(revokedCertificates.getObjects()); 272 } 273 274 public Extensions getExtensions() 275 { 276 return crlExtensions; 277 } 278 279 public ASN1Primitive toASN1Primitive() 280 { 281 ASN1EncodableVector v = new ASN1EncodableVector(); 282 283 if (version != null) 284 { 285 v.add(version); 286 } 287 v.add(signature); 288 v.add(issuer); 289 290 v.add(thisUpdate); 291 if (nextUpdate != null) 292 { 293 v.add(nextUpdate); 294 } 295 296 // Add CRLEntries if they exist 297 if (revokedCertificates != null) 298 { 299 v.add(revokedCertificates); 300 } 301 302 if (crlExtensions != null) 303 { 304 v.add(new DERTaggedObject(0, crlExtensions)); 305 } 306 307 return new DERSequence(v); 308 } 309} 310