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