001: package org.bouncycastle.jce;
002:
003: import java.io.ByteArrayOutputStream;
004: import java.io.IOException;
005: import java.math.BigInteger;
006: import java.security.InvalidKeyException;
007: import java.security.NoSuchAlgorithmException;
008: import java.security.NoSuchProviderException;
009: import java.security.PrivateKey;
010: import java.security.SecureRandom;
011: import java.security.Signature;
012: import java.security.SignatureException;
013: import java.security.cert.CRLException;
014: import java.security.cert.X509CRL;
015: import java.text.SimpleDateFormat;
016: import java.util.Date;
017: import java.util.Hashtable;
018: import java.util.SimpleTimeZone;
019: import java.util.Vector;
020:
021: import org.bouncycastle.asn1.ASN1EncodableVector;
022: import org.bouncycastle.asn1.DERBitString;
023: import org.bouncycastle.asn1.DEREncodable;
024: import org.bouncycastle.asn1.DERInteger;
025: import org.bouncycastle.asn1.DERObjectIdentifier;
026: import org.bouncycastle.asn1.DEROctetString;
027: import org.bouncycastle.asn1.DEROutputStream;
028: import org.bouncycastle.asn1.DERSequence;
029: import org.bouncycastle.asn1.DERUTCTime;
030: import org.bouncycastle.asn1.x509.AlgorithmIdentifier;
031: import org.bouncycastle.asn1.x509.CertificateList;
032: import org.bouncycastle.asn1.x509.TBSCertList;
033: import org.bouncycastle.asn1.x509.V2TBSCertListGenerator;
034: import org.bouncycastle.asn1.x509.X509Extension;
035: import org.bouncycastle.asn1.x509.X509Extensions;
036: import org.bouncycastle.asn1.x509.X509Name;
037: import org.bouncycastle.jce.provider.X509CRLObject;
038: import org.bouncycastle.util.Strings;
039:
040: /**
041: * class to produce an X.509 Version 2 CRL.
042: * <p>
043: * @deprecated use the equivalent class in org.bouncycastle.x509
044: */
045: public class X509V2CRLGenerator {
046: private SimpleDateFormat dateF = new SimpleDateFormat(
047: "yyMMddHHmmss");
048: private SimpleTimeZone tz = new SimpleTimeZone(0, "Z");
049: private V2TBSCertListGenerator tbsGen;
050: private DERObjectIdentifier sigOID;
051: private AlgorithmIdentifier sigAlgId;
052: private String signatureAlgorithm;
053: private Hashtable extensions = null;
054: private Vector extOrdering = null;
055:
056: private static Hashtable algorithms = new Hashtable();
057:
058: static {
059: algorithms.put("MD2WITHRSAENCRYPTION", new DERObjectIdentifier(
060: "1.2.840.113549.1.1.2"));
061: algorithms.put("MD2WITHRSA", new DERObjectIdentifier(
062: "1.2.840.113549.1.1.2"));
063: algorithms.put("MD5WITHRSAENCRYPTION", new DERObjectIdentifier(
064: "1.2.840.113549.1.1.4"));
065: algorithms.put("MD5WITHRSA", new DERObjectIdentifier(
066: "1.2.840.113549.1.1.4"));
067: algorithms.put("SHA1WITHRSAENCRYPTION",
068: new DERObjectIdentifier("1.2.840.113549.1.1.5"));
069: algorithms.put("SHA1WITHRSA", new DERObjectIdentifier(
070: "1.2.840.113549.1.1.5"));
071: algorithms.put("RIPEMD160WITHRSAENCRYPTION",
072: new DERObjectIdentifier("1.3.36.3.3.1.2"));
073: algorithms.put("RIPEMD160WITHRSA", new DERObjectIdentifier(
074: "1.3.36.3.3.1.2"));
075: algorithms.put("SHA1WITHDSA", new DERObjectIdentifier(
076: "1.2.840.10040.4.3"));
077: algorithms.put("DSAWITHSHA1", new DERObjectIdentifier(
078: "1.2.840.10040.4.3"));
079: algorithms.put("SHA1WITHECDSA", new DERObjectIdentifier(
080: "1.2.840.10045.4.1"));
081: algorithms.put("ECDSAWITHSHA1", new DERObjectIdentifier(
082: "1.2.840.10045.4.1"));
083: }
084:
085: public X509V2CRLGenerator() {
086: dateF.setTimeZone(tz);
087:
088: tbsGen = new V2TBSCertListGenerator();
089: }
090:
091: /**
092: * reset the generator
093: */
094: public void reset() {
095: tbsGen = new V2TBSCertListGenerator();
096: }
097:
098: /**
099: * Set the issuer distinguished name - the issuer is the entity whose private key is used to sign the
100: * certificate.
101: */
102: public void setIssuerDN(X509Name issuer) {
103: tbsGen.setIssuer(issuer);
104: }
105:
106: public void setThisUpdate(Date date) {
107: tbsGen.setThisUpdate(new DERUTCTime(dateF.format(date) + "Z"));
108: }
109:
110: public void setNextUpdate(Date date) {
111: tbsGen.setNextUpdate(new DERUTCTime(dateF.format(date) + "Z"));
112: }
113:
114: /**
115: * Reason being as indicated by CRLReason, i.e. CRLReason.KEY_COMPROMISE
116: * or 0 if CRLReason are not to be used
117: **/
118: public void addCRLEntry(BigInteger userCertificate,
119: Date revocationDate, int reason) {
120: tbsGen.addCRLEntry(new DERInteger(userCertificate),
121: new DERUTCTime(dateF.format(revocationDate) + "Z"),
122: reason);
123: }
124:
125: public void setSignatureAlgorithm(String signatureAlgorithm) {
126: this .signatureAlgorithm = signatureAlgorithm;
127:
128: sigOID = (DERObjectIdentifier) algorithms.get(Strings
129: .toUpperCase(signatureAlgorithm));
130:
131: if (sigOID == null) {
132: throw new IllegalArgumentException(
133: "Unknown signature type requested");
134: }
135:
136: sigAlgId = new AlgorithmIdentifier(this .sigOID, null);
137:
138: tbsGen.setSignature(sigAlgId);
139: }
140:
141: /**
142: * add a given extension field for the standard extensions tag (tag 3)
143: */
144: public void addExtension(String OID, boolean critical,
145: DEREncodable value) {
146: this
147: .addExtension(new DERObjectIdentifier(OID), critical,
148: value);
149: }
150:
151: /**
152: * add a given extension field for the standard extensions tag (tag 0)
153: */
154: public void addExtension(DERObjectIdentifier OID, boolean critical,
155: DEREncodable value) {
156: if (extensions == null) {
157: extensions = new Hashtable();
158: extOrdering = new Vector();
159: }
160:
161: ByteArrayOutputStream bOut = new ByteArrayOutputStream();
162: DEROutputStream dOut = new DEROutputStream(bOut);
163:
164: try {
165: dOut.writeObject(value);
166: } catch (IOException e) {
167: throw new IllegalArgumentException("error encoding value: "
168: + e);
169: }
170:
171: this .addExtension(OID, critical, bOut.toByteArray());
172: }
173:
174: /**
175: * add a given extension field for the standard extensions tag (tag 0)
176: */
177: public void addExtension(String OID, boolean critical, byte[] value) {
178: this
179: .addExtension(new DERObjectIdentifier(OID), critical,
180: value);
181: }
182:
183: /**
184: * add a given extension field for the standard extensions tag (tag 0)
185: */
186: public void addExtension(DERObjectIdentifier OID, boolean critical,
187: byte[] value) {
188: if (extensions == null) {
189: extensions = new Hashtable();
190: extOrdering = new Vector();
191: }
192:
193: extensions.put(OID, new X509Extension(critical,
194: new DEROctetString(value)));
195: extOrdering.addElement(OID);
196: }
197:
198: /**
199: * generate an X509 CRL, based on the current issuer and subject
200: * using the default provider "BC".
201: */
202: public X509CRL generateX509CRL(PrivateKey key)
203: throws SecurityException, SignatureException,
204: InvalidKeyException {
205: try {
206: return generateX509CRL(key, "BC", null);
207: } catch (NoSuchProviderException e) {
208: throw new SecurityException("BC provider not installed!");
209: }
210: }
211:
212: /**
213: * generate an X509 CRL, based on the current issuer and subject
214: * using the default provider "BC" and an user defined SecureRandom object as
215: * source of randomness.
216: */
217: public X509CRL generateX509CRL(PrivateKey key, SecureRandom random)
218: throws SecurityException, SignatureException,
219: InvalidKeyException {
220: try {
221: return generateX509CRL(key, "BC", random);
222: } catch (NoSuchProviderException e) {
223: throw new SecurityException("BC provider not installed!");
224: }
225: }
226:
227: /**
228: * generate an X509 certificate, based on the current issuer and subject
229: * using the passed in provider for the signing.
230: */
231: public X509CRL generateX509CRL(PrivateKey key, String provider)
232: throws NoSuchProviderException, SecurityException,
233: SignatureException, InvalidKeyException {
234: return generateX509CRL(key, provider, null);
235: }
236:
237: /**
238: * generate an X509 CRL, based on the current issuer and subject,
239: * using the passed in provider for the signing.
240: */
241: public X509CRL generateX509CRL(PrivateKey key, String provider,
242: SecureRandom random) throws NoSuchProviderException,
243: SecurityException, SignatureException, InvalidKeyException {
244: Signature sig = null;
245:
246: try {
247: sig = Signature.getInstance(sigOID.getId(), provider);
248: } catch (NoSuchAlgorithmException ex) {
249: try {
250: sig = Signature.getInstance(signatureAlgorithm,
251: provider);
252: } catch (NoSuchAlgorithmException e) {
253: throw new SecurityException(
254: "exception creating signature: " + e.toString());
255: }
256: }
257:
258: if (random != null) {
259: sig.initSign(key, random);
260: } else {
261: sig.initSign(key);
262: }
263:
264: if (extensions != null) {
265: tbsGen.setExtensions(new X509Extensions(extOrdering,
266: extensions));
267: }
268:
269: TBSCertList tbsCrl = tbsGen.generateTBSCertList();
270:
271: try {
272: ByteArrayOutputStream bOut = new ByteArrayOutputStream();
273: DEROutputStream dOut = new DEROutputStream(bOut);
274:
275: dOut.writeObject(tbsCrl);
276:
277: sig.update(bOut.toByteArray());
278: } catch (Exception e) {
279: throw new SecurityException(
280: "exception encoding TBS cert - " + e);
281: }
282:
283: // Construct the CRL
284: ASN1EncodableVector v = new ASN1EncodableVector();
285:
286: v.add(tbsCrl);
287: v.add(sigAlgId);
288: v.add(new DERBitString(sig.sign()));
289:
290: try {
291: return new X509CRLObject(new CertificateList(
292: new DERSequence(v)));
293: } catch (CRLException e) {
294: throw new IllegalStateException(
295: "attempt to create malformed CRL: "
296: + e.getMessage());
297: }
298: }
299: }
|