001 /**
002 *
003 * Licensed to the Apache Software Foundation (ASF) under one or more
004 * contributor license agreements. See the NOTICE file distributed with
005 * this work for additional information regarding copyright ownership.
006 * The ASF licenses this file to You under the Apache License, Version 2.0
007 * (the "License"); you may not use this file except in compliance with
008 * the License. You may obtain a copy of the License at
009 *
010 * http://www.apache.org/licenses/LICENSE-2.0
011 *
012 * Unless required by applicable law or agreed to in writing, software
013 * distributed under the License is distributed on an "AS IS" BASIS,
014 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
015 * See the License for the specific language governing permissions and
016 * limitations under the License.
017 */
018
019 package org.apache.geronimo.util.jce;
020
021 import java.io.ByteArrayInputStream;
022 import java.io.ByteArrayOutputStream;
023 import java.math.BigInteger;
024 import java.security.InvalidKeyException;
025 import java.security.NoSuchAlgorithmException;
026 import java.security.NoSuchProviderException;
027 import java.security.PrivateKey;
028 import java.security.PublicKey;
029 import java.security.SecureRandom;
030 import java.security.Signature;
031 import java.security.SignatureException;
032 import java.security.cert.X509Certificate;
033 import java.util.Date;
034 import java.util.Hashtable;
035
036 import org.apache.geronimo.util.asn1.ASN1EncodableVector;
037 import org.apache.geronimo.util.asn1.ASN1InputStream;
038 import org.apache.geronimo.util.asn1.ASN1Sequence;
039 import org.apache.geronimo.util.asn1.DERBitString;
040 import org.apache.geronimo.util.asn1.DERInteger;
041 import org.apache.geronimo.util.asn1.DERNull;
042 import org.apache.geronimo.util.asn1.DERObjectIdentifier;
043 import org.apache.geronimo.util.asn1.DEROutputStream;
044 import org.apache.geronimo.util.asn1.DERSequence;
045 import org.apache.geronimo.util.asn1.x509.AlgorithmIdentifier;
046 import org.apache.geronimo.util.asn1.x509.SubjectPublicKeyInfo;
047 import org.apache.geronimo.util.asn1.x509.TBSCertificateStructure;
048 import org.apache.geronimo.util.asn1.x509.Time;
049 import org.apache.geronimo.util.asn1.x509.V1TBSCertificateGenerator;
050 import org.apache.geronimo.util.asn1.x509.X509CertificateStructure;
051 import org.apache.geronimo.util.asn1.x509.X509Name;
052 import org.apache.geronimo.util.jce.provider.X509CertificateObject;
053
054 /**
055 * class to produce an X.509 Version 1 certificate.
056 *
057 * @deprecated use the equivalent class in org.apache.geronimo.util.x509
058 */
059 public class X509V1CertificateGenerator
060 {
061 private V1TBSCertificateGenerator tbsGen;
062 private DERObjectIdentifier sigOID;
063 private AlgorithmIdentifier sigAlgId;
064 private String signatureAlgorithm;
065
066 private static Hashtable algorithms = new Hashtable();
067
068 static
069 {
070 algorithms.put("MD2WITHRSAENCRYPTION", new DERObjectIdentifier("1.2.840.113549.1.1.2"));
071 algorithms.put("MD2WITHRSA", new DERObjectIdentifier("1.2.840.113549.1.1.2"));
072 algorithms.put("MD5WITHRSAENCRYPTION", new DERObjectIdentifier("1.2.840.113549.1.1.4"));
073 algorithms.put("MD5WITHRSA", new DERObjectIdentifier("1.2.840.113549.1.1.4"));
074 algorithms.put("SHA1WITHRSAENCRYPTION", new DERObjectIdentifier("1.2.840.113549.1.1.5"));
075 algorithms.put("SHA1WITHRSA", new DERObjectIdentifier("1.2.840.113549.1.1.5"));
076 algorithms.put("RIPEMD160WITHRSAENCRYPTION", new DERObjectIdentifier("1.3.36.3.3.1.2"));
077 algorithms.put("RIPEMD160WITHRSA", new DERObjectIdentifier("1.3.36.3.3.1.2"));
078 algorithms.put("SHA1WITHDSA", new DERObjectIdentifier("1.2.840.10040.4.3"));
079 algorithms.put("DSAWITHSHA1", new DERObjectIdentifier("1.2.840.10040.4.3"));
080 algorithms.put("SHA1WITHECDSA", new DERObjectIdentifier("1.2.840.10045.4.1"));
081 algorithms.put("ECDSAWITHSHA1", new DERObjectIdentifier("1.2.840.10045.4.1"));
082 }
083
084 public X509V1CertificateGenerator()
085 {
086 tbsGen = new V1TBSCertificateGenerator();
087 }
088
089 /**
090 * reset the generator
091 */
092 public void reset()
093 {
094 tbsGen = new V1TBSCertificateGenerator();
095 }
096
097 /**
098 * set the serial number for the certificate.
099 */
100 public void setSerialNumber(
101 BigInteger serialNumber)
102 {
103 tbsGen.setSerialNumber(new DERInteger(serialNumber));
104 }
105
106 /**
107 * Set the issuer distinguished name - the issuer is the entity whose private key is used to sign the
108 * certificate.
109 */
110 public void setIssuerDN(
111 X509Name issuer)
112 {
113 tbsGen.setIssuer(issuer);
114 }
115
116 public void setNotBefore(
117 Date date)
118 {
119 tbsGen.setStartDate(new Time(date));
120 }
121
122 public void setNotAfter(
123 Date date)
124 {
125 tbsGen.setEndDate(new Time(date));
126 }
127
128 /**
129 * Set the subject distinguished name. The subject describes the entity associated with the public key.
130 */
131 public void setSubjectDN(
132 X509Name subject)
133 {
134 tbsGen.setSubject(subject);
135 }
136
137 public void setPublicKey(
138 PublicKey key)
139 {
140 try
141 {
142 tbsGen.setSubjectPublicKeyInfo(new SubjectPublicKeyInfo((ASN1Sequence)new ASN1InputStream(
143 new ByteArrayInputStream(key.getEncoded())).readObject()));
144 }
145 catch (Exception e)
146 {
147 throw new IllegalArgumentException("unable to process key - " + e.toString());
148 }
149 }
150
151 public void setSignatureAlgorithm(
152 String signatureAlgorithm)
153 {
154 this.signatureAlgorithm = signatureAlgorithm;
155
156 sigOID = (DERObjectIdentifier)algorithms.get(signatureAlgorithm.toUpperCase());
157
158 if (sigOID == null)
159 {
160 throw new IllegalArgumentException("Unknown signature type requested");
161 }
162
163 sigAlgId = new AlgorithmIdentifier(this.sigOID, new DERNull());
164
165 tbsGen.setSignature(sigAlgId);
166 }
167
168 /**
169 * generate an X509 certificate, based on the current issuer and subject
170 * using the default provider "BC".
171 */
172 public X509Certificate generateX509Certificate(
173 PrivateKey key)
174 throws SecurityException, SignatureException, InvalidKeyException
175 {
176 try
177 {
178 return generateX509Certificate(key, null, null);
179 }
180 catch (NoSuchProviderException e)
181 {
182 throw new SecurityException("JCE provider not installed!");
183 }
184 }
185
186 /**
187 * generate an X509 certificate, based on the current issuer and subject
188 * using the default provider and the passed in source of randomness
189 */
190 public X509Certificate generateX509Certificate(
191 PrivateKey key,
192 SecureRandom random)
193 throws SecurityException, SignatureException, InvalidKeyException
194 {
195 try
196 {
197 return generateX509Certificate(key, null, random);
198 }
199 catch (NoSuchProviderException e)
200 {
201 throw new SecurityException("JCE provider not installed!");
202 }
203 }
204
205 /**
206 * generate an X509 certificate, based on the current issuer and subject,
207 * using the passed in provider for the signing, and the passed in source
208 * of randomness (if required).
209 */
210 public X509Certificate generateX509Certificate(
211 PrivateKey key,
212 String provider)
213 throws NoSuchProviderException, SecurityException, SignatureException, InvalidKeyException
214 {
215 return generateX509Certificate(key, provider, null);
216 }
217
218 /**
219 * generate an X509 certificate, based on the current issuer and subject,
220 * using the passed in provider for the signing, and the passed in source
221 * of randomness (if required).
222 */
223 public X509Certificate generateX509Certificate(
224 PrivateKey key,
225 String provider,
226 SecureRandom random)
227 throws NoSuchProviderException, SecurityException, SignatureException, InvalidKeyException
228 {
229 Signature sig = null;
230
231 try
232 {
233 if (provider == null) {
234 sig = Signature.getInstance(sigOID.getId());
235 }
236 else {
237 sig = Signature.getInstance(sigOID.getId(), provider);
238 }
239 }
240 catch (NoSuchAlgorithmException ex)
241 {
242 try
243 {
244 if (provider == null) {
245 sig = Signature.getInstance(signatureAlgorithm);
246 }
247 else {
248 sig = Signature.getInstance(signatureAlgorithm, provider);
249 }
250 }
251 catch (NoSuchAlgorithmException e)
252 {
253 throw new SecurityException("exception creating signature: " + e.toString());
254 }
255 }
256
257 if (random != null)
258 {
259 sig.initSign(key, random);
260 }
261 else
262 {
263 sig.initSign(key);
264 }
265
266 TBSCertificateStructure tbsCert = tbsGen.generateTBSCertificate();
267
268 try
269 {
270 ByteArrayOutputStream bOut = new ByteArrayOutputStream();
271 DEROutputStream dOut = new DEROutputStream(bOut);
272
273 dOut.writeObject(tbsCert);
274
275 sig.update(bOut.toByteArray());
276 }
277 catch (Exception e)
278 {
279 throw new SecurityException("exception encoding TBS cert - " + e);
280 }
281
282 ASN1EncodableVector v = new ASN1EncodableVector();
283
284 v.add(tbsCert);
285 v.add(sigAlgId);
286 v.add(new DERBitString(sig.sign()));
287
288 return new X509CertificateObject(new X509CertificateStructure(new DERSequence(v)));
289 }
290 }