Docjar: A Java Source and Docuemnt Enginecom.*    java.*    javax.*    org.*    all    new    plug-in

Quick Search    Search Deep

Source code: gnu/classpath/tools/keytool/ExportCmd.java


1   /* ExportCmd.java -- The export command handler of the keytool
2      Copyright (C) 2006 Free Software Foundation, Inc.
3   
4   This file is part of GNU Classpath.
5   
6   GNU Classpath is free software; you can redistribute it and/or modify
7   it under the terms of the GNU General Public License as published by
8   the Free Software Foundation; either version 2, or (at your option)
9   any later version.
10  
11  GNU Classpath is distributed in the hope that it will be useful, but
12  WITHOUT ANY WARRANTY; without even the implied warranty of
13  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
14  General Public License for more details.
15  
16  You should have received a copy of the GNU General Public License
17  along with GNU Classpath; see the file COPYING.  If not, write to the
18  Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA
19  02110-1301 USA.
20  
21  Linking this library statically or dynamically with other modules is
22  making a combined work based on this library.  Thus, the terms and
23  conditions of the GNU General Public License cover the whole
24  combination.
25  
26  As a special exception, the copyright holders of this library give you
27  permission to link this library with independent modules to produce an
28  executable, regardless of the license terms of these independent
29  modules, and to copy and distribute the resulting executable under
30  terms of your choice, provided that you also meet, for each linked
31  independent module, the terms and conditions of the license of that
32  module.  An independent module is a module which is not derived from
33  or based on this library.  If you modify this library, you may extend
34  this exception to your version of the library, but you are not
35  obligated to do so.  If you do not wish to do so, delete this
36  exception statement from your version. */
37  
38  
39  package gnu.classpath.tools.keytool;
40  
41  import gnu.java.security.util.Base64;
42  
43  import java.io.IOException;
44  import java.io.PrintWriter;
45  import java.security.KeyStoreException;
46  import java.security.cert.Certificate;
47  import java.security.cert.CertificateEncodingException;
48  import java.util.logging.Logger;
49  
50  /**
51   * The <b>-export</b> keytool command handler is used to read the certificate
52   * associated with a designated alias from the key store, and write it to a
53   * designated file.
54   * <p>
55   * Possible options for this command are:
56   * <p>
57   * <dl>
58   *      <dt>-alias ALIAS</dt>
59   *      <dd>Every entry, be it a <i>Key Entry</i> or a <i>Trusted
60   *      Certificate</i>, in a key store is uniquely identified by a user-defined
61   *      <i>Alias</i> string. Use this option to specify the <i>Alias</i> to use
62   *      when referring to an entry in the key store. Unless specified otherwise,
63   *      a default value of <code>mykey</code> shall be used when this option is
64   *      omitted from the command line.
65   *      <p></dd>
66   *      
67   *      <dt>-file FILE_NAME</dt>
68   *      <dd>The fully qualified path of the file where the certificate will be
69   *      exported to. If omitted, STDOUT will be used instead.
70   *      <p></dd>
71   *      
72   *      <dt>-storetype STORE_TYP}</dt>
73   *      <dd>Use this option to specify the type of the key store to use. The
74   *      default value, if this option is omitted, is that of the property
75   *      <code>keystore.type</code> in the security properties file, which is
76   *      obtained by invoking the {@link java.security.KeyStore#getDefaultType()}
77   *      static method.
78   *      <p></dd>
79   *      
80   *      <dt>-keystore URL</dt>
81   *      <dd>Use this option to specify the location of the key store to use.
82   *      The default value is a file {@link java.net.URL} referencing the file
83   *      named <code>.keystore</code> located in the path returned by the call to
84   *      {@link java.lang.System#getProperty(String)} using <code>user.home</code>
85   *      as argument.
86   *      <p>
87   *      If a URL was specified, but was found to be malformed --e.g. missing
88   *      protocol element-- the tool will attempt to use the URL value as a file-
89   *      name (with absolute or relative path-name) of a key store --as if the
90   *      protocol was <code>file:</code>.
91   *      <p></dd>
92   *      
93   *      <dt>-storepass PASSWORD</dt>
94   *      <dd>Use this option to specify the password protecting the key store. If
95   *      this option is omitted from the command line, you will be prompted to
96   *      provide a password.
97   *      <p></dd>
98   *      
99   *      <dt>-provider PROVIDER_CLASS_NAME</dt>
100  *      <dd>A fully qualified class name of a Security Provider to add to the
101  *      current list of Security Providers already installed in the JVM in-use.
102  *      If a provider class is specified with this option, and was successfully
103  *      added to the runtime --i.e. it was not already installed-- then the tool
104  *      will attempt to removed this Security Provider before exiting.
105  *      <p></dd>
106  *      
107  *      <dt>-rfc</dt>
108  *      <dd>Use RFC-1421 specifications when encoding the output.
109  *      <p></dd>
110  *      
111  *      <dt>-v</dt>
112  *      <dd>Output the certificate in binary DER encoding. This is the default
113  *      output format of the command if neither <code>-rfc</code> nor
114  *      <code>-v</code> options were detected on the command line. If both this
115  *      option and the <code>-rfc</code> option are detected on the command
116  *      line, the tool will opt for the RFC-1421 style encoding.</dd>
117  * </dl>
118  */
119 class ExportCmd extends Command
120 {
121   private static final Logger log = Logger.getLogger(ExportCmd.class.getName());
122   private String _alias;
123   private String _certFileName;
124   private String _ksType;
125   private String _ksURL;
126   private String _ksPassword;
127   private String _providerClassName;
128   private boolean rfc;
129 
130   // default 0-arguments constructor
131 
132   // public setters -----------------------------------------------------------
133 
134   /** @param alias the alias to use. */
135   public void setAlias(String alias)
136   {
137     this._alias = alias;
138   }
139 
140   /** @param pathName the fully qualified path name of the file to process. */
141   public void setFile(String pathName)
142   {
143     this._certFileName = pathName;
144   }
145 
146   /** @param type the key-store type to use. */
147   public void setStoretype(String type)
148   {
149     this._ksType = type;
150   }
151 
152   /** @param url the key-store URL to use. */
153   public void setKeystore(String url)
154   {
155     this._ksURL = url;
156   }
157 
158   /** @param password the key-store password to use. */
159   public void setStorepass(String password)
160   {
161     this._ksPassword = password;
162   }
163 
164   /** @param className a security provider fully qualified class name to use. */
165   public void setProvider(String className)
166   {
167     this._providerClassName = className;
168   }
169 
170   /**
171    * @param flag whether to use, or not, RFC-1421 format when exporting the
172    *          certificate(s).
173    */
174   public void setRfc(String flag)
175   {
176     this.rfc = Boolean.valueOf(flag).booleanValue();
177   }
178 
179   // life-cycle methods -------------------------------------------------------
180 
181   int processArgs(String[] args, int i)
182   {
183     int limit = args.length;
184     String opt;
185     while (++i < limit)
186       {
187         opt = args[i];
188         log.finest("args[" + i + "]=" + opt);
189         if (opt == null || opt.length() == 0)
190           continue;
191 
192         if ("-alias".equals(opt)) // -alias ALIAS
193           _alias = args[++i];
194         else if ("-file".equals(opt)) // -file FILE_NAME
195           _certFileName = args[++i];
196         else if ("-storetype".equals(opt)) // -storetype STORE_TYPE
197           _ksType = args[++i];
198         else if ("-keystore".equals(opt)) // -keystore URL
199           _ksURL = args[++i];
200         else if ("-storepass".equals(opt)) // -storepass PASSWORD
201           _ksPassword = args[++i];
202         else if ("-provider".equals(opt)) // -provider PROVIDER_CLASS_NAME
203           _providerClassName = args[++i];
204         else if ("-rfc".equals(opt))
205           rfc = true;
206         else if ("-v".equals(opt))
207           verbose = true;
208         else
209           break;
210       }
211 
212     return i;
213   }
214 
215   void setup() throws Exception
216   {
217     setOutputStreamParam(_certFileName);
218     setKeyStoreParams(_providerClassName, _ksType, _ksPassword, _ksURL);
219     setAliasParam(_alias);
220 
221     log.finer("-export handler will use the following options:");
222     log.finer("  -alias=" + alias);
223     log.finer("  -file=" + _certFileName);
224     log.finer("  -storetype=" + storeType);
225     log.finer("  -keystore=" + storeURL);
226     log.finer("  -storepass=" + String.valueOf(storePasswordChars));
227     log.finer("  -provider=" + provider);
228     log.finer("  -rfc=" + rfc);
229     log.finer("  -v=" + verbose);
230   }
231 
232   void start() throws KeyStoreException, CertificateEncodingException,
233       IOException
234   {
235     log.entering(this.getClass().getName(), "start");
236 
237     ensureStoreContainsAlias();
238     Certificate certificate;
239     if (store.isCertificateEntry(alias))
240       {
241         log.fine("Alias [" + alias + "] is a trusted certificate");
242         certificate = store.getCertificate(alias);
243       }
244     else
245       {
246         log.fine("Alias [" + alias + "] is a key entry");
247         Certificate[] chain = store.getCertificateChain(alias);
248         certificate = chain[0];
249       }
250 
251     byte[] derBytes = certificate.getEncoded();
252     if (rfc)
253       {
254         String encoded = Base64.encode(derBytes, 0, derBytes.length, true);
255         PrintWriter pw = new PrintWriter(outStream, true);
256         pw.println("-----BEGIN CERTIFICATE-----");
257         pw.println(encoded);
258         pw.println("-----END CERTIFICATE-----");
259       }
260     else
261       outStream.write(derBytes);
262 
263     // stream is closed in Command.teardown()
264     log.exiting(this.getClass().getName(), "start");
265   }
266 }