View Javadoc

1   package net.sf.bse;
2   
3   /*
4    * Copyright (c) 2002-2003 BSE project contributors 
5    * (http://bse.sourceforge.net/)
6    * 
7    * Permission is hereby granted, free of charge, to any person obtaining a copy
8    * of this software and associated documentation files (the "Software"), to deal
9    * in the Software without restriction, including without limitation the rights
10   * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
11   * copies of the Software, and to permit persons to whom the Software is
12   * furnished to do so, subject to the following conditions:
13   * 
14   * The above copyright notice and this permission notice shall be included in
15   * all copies or substantial portions of the Software.
16   * 
17   * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
18   * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
19   * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.  IN NO EVENT SHALL THE
20   * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
21   * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
22   * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
23   * THE SOFTWARE.
24   */
25  
26  import java.io.FileOutputStream;
27  import java.io.PrintStream;
28  import java.math.BigInteger;
29  import java.security.Key;
30  import java.security.KeyPair;
31  import java.security.KeyPairGenerator;
32  import java.security.SecureRandom;
33  import java.security.cert.X509Certificate;
34  import java.util.Hashtable;
35  import java.util.Map;
36  
37  import org.bouncycastle.asn1.DERConstructedSequence;
38  import org.bouncycastle.asn1.DERIA5String;
39  import org.bouncycastle.asn1.x509.GeneralName;
40  import org.bouncycastle.asn1.x509.GeneralNames;
41  import org.bouncycastle.asn1.x509.X509Extensions;
42  import org.bouncycastle.asn1.x509.X509Name;
43  import org.bouncycastle.jce.X509KeyUsage;
44  import org.bouncycastle.jce.X509V3CertificateGenerator;
45  
46  /***
47   * Command to generate an MHP root certificate.
48   *
49   * @author Bill Foote (bill.foote@sun.com)
50   * @author Aleksi Peebles (aleksi.peebles@infocast.fi)
51   * @version $Revision: 1.1 $ $Date: 2003/01/17 14:40:19 $
52   */
53  public class GenerateRootCertificate extends Command
54  {    
55      public GenerateRootCertificate(Map args)
56      {
57          super(args);
58      }
59      
60      public void usageMessage(PrintStream out)
61      {
62          out.println(
63  "Command:  root\n\n" +
64  
65  "    Generates an MHP root certificate\n\n" +
66  
67  "    Arguments:\n\n" +
68  
69  "        name:        Subject commonName of root CA\n" +
70  "        country:     Subject countryName of root CA\n" +
71  "        email:       Subject e-mail address of root CA\n" +
72  "        validFrom:   Date cert is valid from, in dd/mm/yyyy format\n" +
73  "        validUntil:  Date cert is valid until, in dd/mm/yyyy format\n" +
74  "        serial:      Serial number of certificate\n" +
75  "        strength:    Length of key in bits\n" +
76  "        file:        Where to store the results\n");
77      }
78      
79      public String[] getRequiredArgs()
80      {
81          return new String[] { "name:", "country:", "email:", "validFrom:", 
82              "validUntil:", "serial:", "strength:", "file:" };
83      }
84      
85      public String[] getOptionalArgs()
86      {
87          return null;
88      }
89      
90      public void run() throws Exception
91      {
92          System.out.println("Generating root certificate.");
93          
94          // Do a bit of argument checking before time-consuming operations...
95          getDateArg("validFrom:");
96          getDateArg("validUntil:");
97          
98          KeyPairGenerator kpGen = KeyPairGenerator.getInstance("RSA", "BC");
99  
100         // key bit length, 4096 is max guaranteed by MHP
101         int strength = Integer.parseInt(getArg("strength:"));
102         
103         kpGen.initialize(strength, new SecureRandom());
104         
105         System.out.println("Generating key pair. This may take a few minutes.");
106         KeyPair pair = kpGen.genKeyPair();
107         
108         X509V3CertificateGenerator cg = new X509V3CertificateGenerator();
109         cg.reset();
110 
111         X509Name subject = null;
112         Hashtable ht = new Hashtable();
113         ht.put(X509Name.C, getArg("country:"));
114         ht.put(X509Name.CN, getArg("name:"));
115         subject = new X509Name(ht);
116 
117         cg.setIssuerDN(subject); // Root CA: issuer == subject
118         cg.setSubjectDN(subject);
119         cg.setNotBefore(getDateArg("validFrom:"));
120         cg.setNotAfter(getDateArg("validUntil:"));
121         cg.setPublicKey(pair.getPublic());
122         cg.setSerialNumber(new BigInteger(getArg("serial:")));
123         cg.setSignatureAlgorithm("MD5WITHRSA"); // SHA1WITHRSA is OK, too
124         
125         cg.addExtension(X509Extensions.KeyUsage.getId(), true,
126             new X509KeyUsage(
127             X509KeyUsage.keyCertSign)); // leaf KeyUsage is different
128         
129         GeneralName gn = new GeneralName(new DERIA5String(getArg("email:")), 1);
130         DERConstructedSequence seq = new DERConstructedSequence();
131         seq.addObject(gn);
132         GeneralNames san = new GeneralNames(seq);
133         cg.addExtension(
134             X509Extensions.SubjectAlternativeName.getId(), false, san);
135         
136         cg.addExtension(
137             X509Extensions.IssuerAlternativeName.getId(), false, san);
138         
139         X509Certificate cert = 
140             cg.generateX509Certificate(pair.getPrivate(), "BC");
141         
142         // Now, write private key
143         Key key = pair.getPrivate();
144         String fn = getArg("file:") + "_private.pkcs";
145         System.out.println("Writing root private key in "
146             + key.getFormat() + " format to " + fn + ".");
147         FileOutputStream str = new FileOutputStream(fn);
148         str.write(key.getEncoded());
149         str.close();
150 
151         // Then public certificate
152         fn = getArg("file:") + "_public.x509.crt";
153         System.out.println("Writing root cert to " + fn + ".");
154         str = new FileOutputStream(fn);
155         str.write(cert.getEncoded());
156         str.close();
157 
158         System.out.println("Done!");
159         System.out.println();
160     }
161 }