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