View Javadoc

1   /**
2    *
3    *  Licensed to the Apache Software Foundation (ASF) under one or more
4    *  contributor license agreements.  See the NOTICE file distributed with
5    *  this work for additional information regarding copyright ownership.
6    *  The ASF licenses this file to You under the Apache License, Version 2.0
7    *  (the "License"); you may not use this file except in compliance with
8    *  the License.  You may obtain a copy of the License at
9    *
10   *     http://www.apache.org/licenses/LICENSE-2.0
11   *
12   *  Unless required by applicable law or agreed to in writing, software
13   *  distributed under the License is distributed on an "AS IS" BASIS,
14   *  WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
15   *  See the License for the specific language governing permissions and
16   *  limitations under the License.
17   */
18  
19  package org.apache.geronimo.util.jce;
20  
21  import java.io.ByteArrayInputStream;
22  import java.io.ByteArrayOutputStream;
23  import java.math.BigInteger;
24  import java.security.InvalidKeyException;
25  import java.security.NoSuchAlgorithmException;
26  import java.security.NoSuchProviderException;
27  import java.security.PrivateKey;
28  import java.security.PublicKey;
29  import java.security.SecureRandom;
30  import java.security.Signature;
31  import java.security.SignatureException;
32  import java.security.cert.X509Certificate;
33  import java.util.Date;
34  import java.util.Hashtable;
35  
36  import org.apache.geronimo.util.asn1.ASN1EncodableVector;
37  import org.apache.geronimo.util.asn1.ASN1InputStream;
38  import org.apache.geronimo.util.asn1.ASN1Sequence;
39  import org.apache.geronimo.util.asn1.DERBitString;
40  import org.apache.geronimo.util.asn1.DERInteger;
41  import org.apache.geronimo.util.asn1.DERNull;
42  import org.apache.geronimo.util.asn1.DERObjectIdentifier;
43  import org.apache.geronimo.util.asn1.DEROutputStream;
44  import org.apache.geronimo.util.asn1.DERSequence;
45  import org.apache.geronimo.util.asn1.x509.AlgorithmIdentifier;
46  import org.apache.geronimo.util.asn1.x509.SubjectPublicKeyInfo;
47  import org.apache.geronimo.util.asn1.x509.TBSCertificateStructure;
48  import org.apache.geronimo.util.asn1.x509.Time;
49  import org.apache.geronimo.util.asn1.x509.V1TBSCertificateGenerator;
50  import org.apache.geronimo.util.asn1.x509.X509CertificateStructure;
51  import org.apache.geronimo.util.asn1.x509.X509Name;
52  import org.apache.geronimo.util.jce.provider.X509CertificateObject;
53  
54  /**
55   * class to produce an X.509 Version 1 certificate.
56   *
57   * @deprecated use the equivalent class in org.apache.geronimo.util.x509
58   */
59  public class X509V1CertificateGenerator
60  {
61      private V1TBSCertificateGenerator   tbsGen;
62      private DERObjectIdentifier         sigOID;
63      private AlgorithmIdentifier         sigAlgId;
64      private String                      signatureAlgorithm;
65  
66      private static Hashtable            algorithms = new Hashtable();
67  
68      static
69      {
70          algorithms.put("MD2WITHRSAENCRYPTION", new DERObjectIdentifier("1.2.840.113549.1.1.2"));
71          algorithms.put("MD2WITHRSA", new DERObjectIdentifier("1.2.840.113549.1.1.2"));
72          algorithms.put("MD5WITHRSAENCRYPTION", new DERObjectIdentifier("1.2.840.113549.1.1.4"));
73          algorithms.put("MD5WITHRSA", new DERObjectIdentifier("1.2.840.113549.1.1.4"));
74          algorithms.put("SHA1WITHRSAENCRYPTION", new DERObjectIdentifier("1.2.840.113549.1.1.5"));
75          algorithms.put("SHA1WITHRSA", new DERObjectIdentifier("1.2.840.113549.1.1.5"));
76          algorithms.put("RIPEMD160WITHRSAENCRYPTION", new DERObjectIdentifier("1.3.36.3.3.1.2"));
77          algorithms.put("RIPEMD160WITHRSA", new DERObjectIdentifier("1.3.36.3.3.1.2"));
78          algorithms.put("SHA1WITHDSA", new DERObjectIdentifier("1.2.840.10040.4.3"));
79          algorithms.put("DSAWITHSHA1", new DERObjectIdentifier("1.2.840.10040.4.3"));
80          algorithms.put("SHA1WITHECDSA", new DERObjectIdentifier("1.2.840.10045.4.1"));
81          algorithms.put("ECDSAWITHSHA1", new DERObjectIdentifier("1.2.840.10045.4.1"));
82      }
83  
84      public X509V1CertificateGenerator()
85      {
86          tbsGen = new V1TBSCertificateGenerator();
87      }
88  
89      /**
90       * reset the generator
91       */
92      public void reset()
93      {
94          tbsGen = new V1TBSCertificateGenerator();
95      }
96  
97      /**
98       * set the serial number for the certificate.
99       */
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 }