001package org.apache.commons.ssl.org.bouncycastle.asn1.x509; 002 003import java.io.IOException; 004 005import org.apache.commons.ssl.org.bouncycastle.asn1.ASN1EncodableVector; 006import org.apache.commons.ssl.org.bouncycastle.asn1.ASN1GeneralizedTime; 007import org.apache.commons.ssl.org.bouncycastle.asn1.ASN1Integer; 008import org.apache.commons.ssl.org.bouncycastle.asn1.ASN1Sequence; 009import org.apache.commons.ssl.org.bouncycastle.asn1.ASN1UTCTime; 010import org.apache.commons.ssl.org.bouncycastle.asn1.DEROctetString; 011import org.apache.commons.ssl.org.bouncycastle.asn1.DERSequence; 012import org.apache.commons.ssl.org.bouncycastle.asn1.DERTaggedObject; 013import org.apache.commons.ssl.org.bouncycastle.asn1.x500.X500Name; 014 015/** 016 * Generator for Version 2 TBSCertList structures. 017 * <pre> 018 * TBSCertList ::= SEQUENCE { 019 * version Version OPTIONAL, 020 * -- if present, shall be v2 021 * signature AlgorithmIdentifier, 022 * issuer Name, 023 * thisUpdate Time, 024 * nextUpdate Time OPTIONAL, 025 * revokedCertificates SEQUENCE OF SEQUENCE { 026 * userCertificate CertificateSerialNumber, 027 * revocationDate Time, 028 * crlEntryExtensions Extensions OPTIONAL 029 * -- if present, shall be v2 030 * } OPTIONAL, 031 * crlExtensions [0] EXPLICIT Extensions OPTIONAL 032 * -- if present, shall be v2 033 * } 034 * </pre> 035 * 036 * <b>Note: This class may be subject to change</b> 037 */ 038public class V2TBSCertListGenerator 039{ 040 private ASN1Integer version = new ASN1Integer(1); 041 private AlgorithmIdentifier signature; 042 private X500Name issuer; 043 private Time thisUpdate, nextUpdate=null; 044 private Extensions extensions = null; 045 private ASN1EncodableVector crlentries = new ASN1EncodableVector(); 046 047 private final static ASN1Sequence[] reasons; 048 049 static 050 { 051 reasons = new ASN1Sequence[11]; 052 053 reasons[0] = createReasonExtension(CRLReason.unspecified); 054 reasons[1] = createReasonExtension(CRLReason.keyCompromise); 055 reasons[2] = createReasonExtension(CRLReason.cACompromise); 056 reasons[3] = createReasonExtension(CRLReason.affiliationChanged); 057 reasons[4] = createReasonExtension(CRLReason.superseded); 058 reasons[5] = createReasonExtension(CRLReason.cessationOfOperation); 059 reasons[6] = createReasonExtension(CRLReason.certificateHold); 060 reasons[7] = createReasonExtension(7); // 7 -> unknown 061 reasons[8] = createReasonExtension(CRLReason.removeFromCRL); 062 reasons[9] = createReasonExtension(CRLReason.privilegeWithdrawn); 063 reasons[10] = createReasonExtension(CRLReason.aACompromise); 064 } 065 066 public V2TBSCertListGenerator() 067 { 068 } 069 070 071 public void setSignature( 072 AlgorithmIdentifier signature) 073 { 074 this.signature = signature; 075 } 076 077 /** 078 * @deprecated use X500Name method 079 */ 080 public void setIssuer( 081 X509Name issuer) 082 { 083 this.issuer = X500Name.getInstance(issuer.toASN1Primitive()); 084 } 085 086 public void setIssuer(X500Name issuer) 087 { 088 this.issuer = issuer; 089 } 090 091 public void setThisUpdate( 092 ASN1UTCTime thisUpdate) 093 { 094 this.thisUpdate = new Time(thisUpdate); 095 } 096 097 public void setNextUpdate( 098 ASN1UTCTime nextUpdate) 099 { 100 this.nextUpdate = new Time(nextUpdate); 101 } 102 103 public void setThisUpdate( 104 Time thisUpdate) 105 { 106 this.thisUpdate = thisUpdate; 107 } 108 109 public void setNextUpdate( 110 Time nextUpdate) 111 { 112 this.nextUpdate = nextUpdate; 113 } 114 115 public void addCRLEntry( 116 ASN1Sequence crlEntry) 117 { 118 crlentries.add(crlEntry); 119 } 120 121 public void addCRLEntry(ASN1Integer userCertificate, ASN1UTCTime revocationDate, int reason) 122 { 123 addCRLEntry(userCertificate, new Time(revocationDate), reason); 124 } 125 126 public void addCRLEntry(ASN1Integer userCertificate, Time revocationDate, int reason) 127 { 128 addCRLEntry(userCertificate, revocationDate, reason, null); 129 } 130 131 public void addCRLEntry(ASN1Integer userCertificate, Time revocationDate, int reason, ASN1GeneralizedTime invalidityDate) 132 { 133 if (reason != 0) 134 { 135 ASN1EncodableVector v = new ASN1EncodableVector(); 136 137 if (reason < reasons.length) 138 { 139 if (reason < 0) 140 { 141 throw new IllegalArgumentException("invalid reason value: " + reason); 142 } 143 v.add(reasons[reason]); 144 } 145 else 146 { 147 v.add(createReasonExtension(reason)); 148 } 149 150 if (invalidityDate != null) 151 { 152 v.add(createInvalidityDateExtension(invalidityDate)); 153 } 154 155 internalAddCRLEntry(userCertificate, revocationDate, new DERSequence(v)); 156 } 157 else if (invalidityDate != null) 158 { 159 ASN1EncodableVector v = new ASN1EncodableVector(); 160 161 v.add(createInvalidityDateExtension(invalidityDate)); 162 163 internalAddCRLEntry(userCertificate, revocationDate, new DERSequence(v)); 164 } 165 else 166 { 167 addCRLEntry(userCertificate, revocationDate, null); 168 } 169 } 170 171 private void internalAddCRLEntry(ASN1Integer userCertificate, Time revocationDate, ASN1Sequence extensions) 172 { 173 ASN1EncodableVector v = new ASN1EncodableVector(); 174 175 v.add(userCertificate); 176 v.add(revocationDate); 177 178 if (extensions != null) 179 { 180 v.add(extensions); 181 } 182 183 addCRLEntry(new DERSequence(v)); 184 } 185 186 public void addCRLEntry(ASN1Integer userCertificate, Time revocationDate, Extensions extensions) 187 { 188 ASN1EncodableVector v = new ASN1EncodableVector(); 189 190 v.add(userCertificate); 191 v.add(revocationDate); 192 193 if (extensions != null) 194 { 195 v.add(extensions); 196 } 197 198 addCRLEntry(new DERSequence(v)); 199 } 200 201 public void setExtensions( 202 X509Extensions extensions) 203 { 204 setExtensions(Extensions.getInstance(extensions)); 205 } 206 207 public void setExtensions( 208 Extensions extensions) 209 { 210 this.extensions = extensions; 211 } 212 213 public TBSCertList generateTBSCertList() 214 { 215 if ((signature == null) || (issuer == null) || (thisUpdate == null)) 216 { 217 throw new IllegalStateException("Not all mandatory fields set in V2 TBSCertList generator."); 218 } 219 220 ASN1EncodableVector v = new ASN1EncodableVector(); 221 222 v.add(version); 223 v.add(signature); 224 v.add(issuer); 225 226 v.add(thisUpdate); 227 if (nextUpdate != null) 228 { 229 v.add(nextUpdate); 230 } 231 232 // Add CRLEntries if they exist 233 if (crlentries.size() != 0) 234 { 235 v.add(new DERSequence(crlentries)); 236 } 237 238 if (extensions != null) 239 { 240 v.add(new DERTaggedObject(0, extensions)); 241 } 242 243 return new TBSCertList(new DERSequence(v)); 244 } 245 246 private static ASN1Sequence createReasonExtension(int reasonCode) 247 { 248 ASN1EncodableVector v = new ASN1EncodableVector(); 249 250 CRLReason crlReason = CRLReason.lookup(reasonCode); 251 252 try 253 { 254 v.add(Extension.reasonCode); 255 v.add(new DEROctetString(crlReason.getEncoded())); 256 } 257 catch (IOException e) 258 { 259 throw new IllegalArgumentException("error encoding reason: " + e); 260 } 261 262 return new DERSequence(v); 263 } 264 265 private static ASN1Sequence createInvalidityDateExtension(ASN1GeneralizedTime invalidityDate) 266 { 267 ASN1EncodableVector v = new ASN1EncodableVector(); 268 269 try 270 { 271 v.add(Extension.invalidityDate); 272 v.add(new DEROctetString(invalidityDate.getEncoded())); 273 } 274 catch (IOException e) 275 { 276 throw new IllegalArgumentException("error encoding reason: " + e); 277 } 278 279 return new DERSequence(v); 280 } 281}