OpenCores
URL https://opencores.org/ocsvn/openrisc/openrisc/trunk

Subversion Repositories openrisc

[/] [openrisc/] [trunk/] [gnu-dev/] [or1k-gcc/] [libjava/] [classpath/] [tools/] [gnu/] [classpath/] [tools/] [keytool/] [CertReqCmd.java] - Blame information for rev 779

Details | Compare with Previous | View Log

Line No. Rev Author Line
1 779 jeremybenn
/* CertReqCmd.java -- The certreq command handler of the keytool
2
   Copyright (C) 2006, 2007 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.classpath.Configuration;
42
import gnu.classpath.tools.common.ClasspathToolParser;
43
import gnu.classpath.tools.getopt.Option;
44
import gnu.classpath.tools.getopt.OptionException;
45
import gnu.classpath.tools.getopt.OptionGroup;
46
import gnu.classpath.tools.getopt.Parser;
47
import gnu.java.security.OID;
48
import gnu.java.security.der.BitString;
49
import gnu.java.security.der.DER;
50
import gnu.java.security.der.DERReader;
51
import gnu.java.security.der.DERValue;
52
import gnu.java.security.der.DERWriter;
53
import gnu.java.util.Base64;
54
 
55
import java.io.ByteArrayOutputStream;
56
import java.io.IOException;
57
import java.io.PrintWriter;
58
import java.math.BigInteger;
59
import java.security.InvalidKeyException;
60
import java.security.Key;
61
import java.security.KeyStoreException;
62
import java.security.NoSuchAlgorithmException;
63
import java.security.PrivateKey;
64
import java.security.PublicKey;
65
import java.security.SignatureException;
66
import java.security.UnrecoverableKeyException;
67
import java.security.cert.Certificate;
68
import java.security.cert.X509Certificate;
69
import java.util.ArrayList;
70
import java.util.logging.Logger;
71
 
72
import javax.security.auth.callback.UnsupportedCallbackException;
73
import javax.security.auth.x500.X500Principal;
74
 
75
/**
76
 * The <b>-certreq</b> keytool command handler is used to generate a Certificate
77
 * Signing Request (CSR) in PKCS#10 format.
78
 * <p>
79
 * The ASN.1 specification of a CSR, as stated in RFC-2986 is as follows:
80
 * <p>
81
 * <pre>
82
 * CertificationRequest ::= SEQUENCE {
83
 *   certificationRequestInfo  CertificationRequestInfo,
84
 *   signatureAlgorithm        AlgorithmIdentifier,
85
 *   signature                 BIT STRING
86
 * }
87
 *
88
 * CertificationRequestInfo ::= SEQUENCE {
89
 *   version           INTEGER -- v1(0)
90
 *   subject           Name,
91
 *   subjectPKInfo     SubjectPublicKeyInfo,
92
 *   attributes    [0] IMPLICIT Attributes -- see note later
93
 * }
94
 *
95
 * SubjectPublicKeyInfo ::= SEQUENCE {
96
 *   algorithm         AlgorithmIdentifier,
97
 *   subjectPublicKey  BIT STRING
98
 * }
99
 * </pre>
100
 * <b>IMPORTANT</b>: Some documentation (e.g. RSA examples) claims that the
101
 * <code>attributes</code> field is <i>OPTIONAL</i> while <i>RFC-2986</i>
102
 * implies the opposite. This implementation considers this field, by default,
103
 * as <i>OPTIONAL</i>, unless the option <code>-attributes</code> is included
104
 * on the command line.
105
 * <p>
106
 * Possible options for this command are:
107
 * <p>
108
 * <dl>
109
 *      <dt>-alias ALIAS</dt>
110
 *      <dd>Every entry, be it a <i>Key Entry</i> or a <i>Trusted
111
 *      Certificate</i>, in a key store is uniquely identified by a user-defined
112
 *      <i>Alias</i> string. Use this option to specify the <i>Alias</i> to use
113
 *      when referring to an entry in the key store. Unless specified otherwise,
114
 *      a default value of <code>mykey</code> shall be used when this option is
115
 *      omitted from the command line.
116
 *      <p></dd>
117
 *
118
 *      <dt>-sigalg ALGORITHM</dt>
119
 *      <dd>The canonical name of the digital signature algorithm to use for
120
 *      signing the certificate. If this option is omitted, a default value will
121
 *      be chosen based on the type of the private key associated with the
122
 *      designated <i>Alias</i>. If the private key is a <code>DSA</code> one,
123
 *      the value for the signature algorithm will be <code>SHA1withDSA</code>.
124
 *      If on the other hand the private key is an <code>RSA</code> one, then
125
 *      the tool will use <code>MD5withRSA</code> as the signature algorithm.
126
 *      <p></dd>
127
 *
128
 *      <dt>-file FILE_NAME</dt>
129
 *
130
 *      <dt>-keypass PASSWORD</dt>
131
 *
132
 *      <dt>-storetype STORE_TYPE</dt>
133
 *      <dd>Use this option to specify the type of the key store to use. The
134
 *      default value, if this option is omitted, is that of the property
135
 *      <code>keystore.type</code> in the security properties file, which is
136
 *      obtained by invoking the {@link java.security.KeyStore#getDefaultType()}
137
 *      static method.
138
 *      <p></dd>
139
 *
140
 *      <dt>-keystore URL</dt>
141
 *      <dd>Use this option to specify the location of the key store to use.
142
 *      The default value is a file {@link java.net.URL} referencing the file
143
 *      named <code>.keystore</code> located in the path returned by the call to
144
 *      {@link java.lang.System#getProperty(String)} using <code>user.home</code>
145
 *      as argument.
146
 *      <p>
147
 *      If a URL was specified, but was found to be malformed --e.g. missing
148
 *      protocol element-- the tool will attempt to use the URL value as a file-
149
 *      name (with absolute or relative path-name) of a key store --as if the
150
 *      protocol was <code>file:</code>.
151
 *      <p></dd>
152
 *
153
 *      <dt>-storepass PASSWORD</dt>
154
 *      <dd>Use this option to specify the password protecting the key store. If
155
 *      this option is omitted from the command line, you will be prompted to
156
 *      provide a password.
157
 *      <p></dd>
158
 *
159
 *      <dt>-provider PROVIDER_CLASS_NAME</dt>
160
 *      <dd>A fully qualified class name of a Security Provider to add to the
161
 *      current list of Security Providers already installed in the JVM in-use.
162
 *      If a provider class is specified with this option, and was successfully
163
 *      added to the runtime --i.e. it was not already installed-- then the tool
164
 *      will attempt to removed this Security Provider before exiting.
165
 *      <p></dd>
166
 *
167
 *      <dt>-v</dt>
168
 *      <dd>Use this option to enable more verbose output.
169
 *      <p></dd>
170
 *
171
 *      <dt>-attributes</dt>
172
 *      <dd>Use this option to force the tool to encode a NULL DER value in the
173
 *      CSR as the value of the Attributes field.</dd>
174
 * </dl>
175
 */
176
class CertReqCmd extends Command
177
{
178
  private static final Logger log = Logger.getLogger(CertReqCmd.class.getName());
179
  private static final String ATTRIBUTES_OPT = "attributes"; //$NON-NLS-1$
180
  protected String _alias;
181
  protected String _sigAlgorithm;
182
  protected String _certReqFileName;
183
  protected String _password;
184
  protected String _ksType;
185
  protected String _ksURL;
186
  protected String _ksPassword;
187
  protected String _providerClassName;
188
  protected boolean nullAttributes;
189
 
190
  // default 0-arguments constructor
191
 
192
  // public setters -----------------------------------------------------------
193
 
194
  /** @param alias the alias to use. */
195
  public void setAlias(String alias)
196
  {
197
    this._alias = alias;
198
  }
199
 
200
  /**
201
   * @param algorithm the canonical name of the digital signature algorithm to
202
   *          use.
203
   */
204
  public void setSigalg(String algorithm)
205
  {
206
    this._sigAlgorithm = algorithm;
207
  }
208
 
209
  /** @param pathName the fully qualified path name of the file to process. */
210
  public void setFile(String pathName)
211
  {
212
    this._certReqFileName = pathName;
213
  }
214
 
215
  /** @param password the (private) key password to use. */
216
  public void setKeypass(String password)
217
  {
218
    this._password = password;
219
  }
220
 
221
  /** @param type the key-store type to use. */
222
  public void setStoretype(String type)
223
  {
224
    this._ksType = type;
225
  }
226
 
227
  /** @param url the key-store URL to use. */
228
  public void setKeystore(String url)
229
  {
230
    this._ksURL = url;
231
  }
232
 
233
  /** @param password the key-store password to use. */
234
  public void setStorepass(String password)
235
  {
236
    this._ksPassword = password;
237
  }
238
 
239
  /** @param className a security provider fully qualified class name to use. */
240
  public void setProvider(String className)
241
  {
242
    this._providerClassName = className;
243
  }
244
 
245
  /**
246
   * @param flag whether to use, or not, a <code>NULL</code> DER value for
247
   *          the certificate's Attributes field.
248
   */
249
  public void setAttributes(String flag)
250
  {
251
    this.nullAttributes = Boolean.valueOf(flag).booleanValue();
252
  }
253
 
254
  // life-cycle methods -------------------------------------------------------
255
 
256
  void setup() throws Exception
257
  {
258
    setOutputStreamParam(_certReqFileName);
259
    setKeyStoreParams(_providerClassName, _ksType, _ksPassword, _ksURL);
260
    setAliasParam(_alias);
261
    setKeyPasswordNoPrompt(_password);
262
    if (Configuration.DEBUG)
263
      {
264
        log.fine("-certreq handler will use the following options:"); //$NON-NLS-1$
265
        log.fine("  -alias=" + alias); //$NON-NLS-1$
266
        log.fine("  -sigalg=" + _sigAlgorithm); //$NON-NLS-1$
267
        log.fine("  -file=" + _certReqFileName); //$NON-NLS-1$
268
        log.fine("  -storetype=" + storeType); //$NON-NLS-1$
269
        log.fine("  -keystore=" + storeURL); //$NON-NLS-1$
270
        log.fine("  -provider=" + provider); //$NON-NLS-1$
271
        log.fine("  -v=" + verbose); //$NON-NLS-1$
272
        log.fine("  -attributes=" + nullAttributes); //$NON-NLS-1$
273
      }
274
  }
275
 
276
  void start() throws KeyStoreException, NoSuchAlgorithmException, IOException,
277
      UnsupportedCallbackException, UnrecoverableKeyException,
278
      InvalidKeyException, SignatureException
279
  {
280
    if (Configuration.DEBUG)
281
      log.entering(this.getClass().getName(), "start"); //$NON-NLS-1$
282
    // 1. get the key entry and certificate chain associated to alias
283
    Key privateKey = getAliasPrivateKey();
284
    Certificate[] chain = store.getCertificateChain(alias);
285
 
286
    // 2. get alias's DN and public key to use in the CSR
287
    X509Certificate bottomCertificate = (X509Certificate) chain[0];
288
    X500Principal aliasName = bottomCertificate.getIssuerX500Principal();
289
    PublicKey publicKey = bottomCertificate.getPublicKey();
290
 
291
    // 3. generate the CSR
292
    setSignatureAlgorithmParam(_sigAlgorithm, privateKey);
293
    byte[] derBytes = getCSR(aliasName, publicKey, (PrivateKey) privateKey);
294
 
295
    // 4. encode it in base-64 and write it to outStream
296
    String encoded = Base64.encode(derBytes, 72);
297
    PrintWriter writer = new PrintWriter(outStream, true);
298
    writer.println("-----BEGIN NEW CERTIFICATE REQUEST-----"); //$NON-NLS-1$
299
    writer.println(encoded);
300
    writer.println("-----END NEW CERTIFICATE REQUEST-----"); //$NON-NLS-1$
301
 
302
    if (verbose)
303
      {
304
        if (! systemOut)
305
          System.out.println(Messages.getFormattedString("CertReqCmd.27", //$NON-NLS-1$
306
                                                         _certReqFileName));
307
        System.out.println(Messages.getString("CertReqCmd.28")); //$NON-NLS-1$
308
      }
309
 
310
    writer.close();
311
    if (Configuration.DEBUG)
312
      log.exiting(this.getClass().getName(), "start"); //$NON-NLS-1$
313
  }
314
 
315
  // own methods --------------------------------------------------------------
316
 
317
  Parser getParser()
318
  {
319
    if (Configuration.DEBUG)
320
      log.entering(this.getClass().getName(), "getParser"); //$NON-NLS-1$
321
    Parser result = new ClasspathToolParser(Main.CERTREQ_CMD, true);
322
    result.setHeader(Messages.getString("CertReqCmd.25")); //$NON-NLS-1$
323
    result.setFooter(Messages.getString("CertReqCmd.24")); //$NON-NLS-1$
324
    OptionGroup options = new OptionGroup(Messages.getString("CertReqCmd.23")); //$NON-NLS-1$
325
    options.add(new Option(Main.ALIAS_OPT,
326
                           Messages.getString("CertReqCmd.22"), //$NON-NLS-1$
327
                           Messages.getString("CertReqCmd.21")) //$NON-NLS-1$
328
    {
329
      public void parsed(String argument) throws OptionException
330
      {
331
        _alias = argument;
332
      }
333
    });
334
    options.add(new Option(Main.SIGALG_OPT,
335
                           Messages.getString("CertReqCmd.20"), //$NON-NLS-1$
336
                           Messages.getString("CertReqCmd.19")) //$NON-NLS-1$
337
    {
338
      public void parsed(String argument) throws OptionException
339
      {
340
        _sigAlgorithm = argument;
341
      }
342
    });
343
    options.add(new Option(Main.FILE_OPT,
344
                           Messages.getString("CertReqCmd.18"), //$NON-NLS-1$
345
                           Messages.getString("CertReqCmd.17")) //$NON-NLS-1$
346
    {
347
      public void parsed(String argument) throws OptionException
348
      {
349
        _certReqFileName = argument;
350
      }
351
    });
352
    options.add(new Option(Main.KEYPASS_OPT,
353
                           Messages.getString("CertReqCmd.16"), //$NON-NLS-1$
354
                           Messages.getString("CertReqCmd.9")) //$NON-NLS-1$
355
    {
356
      public void parsed(String argument) throws OptionException
357
      {
358
        _password = argument;
359
      }
360
    });
361
    options.add(new Option(Main.STORETYPE_OPT,
362
                           Messages.getString("CertReqCmd.14"), //$NON-NLS-1$
363
                           Messages.getString("CertReqCmd.13")) //$NON-NLS-1$
364
    {
365
      public void parsed(String argument) throws OptionException
366
      {
367
        _ksType = argument;
368
      }
369
    });
370
    options.add(new Option(Main.KEYSTORE_OPT,
371
                           Messages.getString("CertReqCmd.12"), //$NON-NLS-1$
372
                           Messages.getString("CertReqCmd.11")) //$NON-NLS-1$
373
    {
374
      public void parsed(String argument) throws OptionException
375
      {
376
        _ksURL = argument;
377
      }
378
    });
379
    options.add(new Option(Main.STOREPASS_OPT,
380
                           Messages.getString("CertReqCmd.10"), //$NON-NLS-1$
381
                           Messages.getString("CertReqCmd.9")) //$NON-NLS-1$
382
    {
383
      public void parsed(String argument) throws OptionException
384
      {
385
        _ksPassword = argument;
386
      }
387
    });
388
    options.add(new Option(Main.PROVIDER_OPT,
389
                           Messages.getString("CertReqCmd.8"), //$NON-NLS-1$
390
                           Messages.getString("CertReqCmd.7")) //$NON-NLS-1$
391
    {
392
      public void parsed(String argument) throws OptionException
393
      {
394
        _providerClassName = argument;
395
      }
396
    });
397
    options.add(new Option(Main.VERBOSE_OPT,
398
                           Messages.getString("CertReqCmd.6")) //$NON-NLS-1$
399
    {
400
      public void parsed(String argument) throws OptionException
401
      {
402
        verbose = true;
403
      }
404
    });
405
    options.add(new Option(ATTRIBUTES_OPT,
406
                           Messages.getString("CertReqCmd.5")) //$NON-NLS-1$
407
    {
408
      public void parsed(String argument) throws OptionException
409
      {
410
        nullAttributes = true;
411
      }
412
    });
413
    result.add(options);
414
    if (Configuration.DEBUG)
415
      log.exiting(this.getClass().getName(), "getParser", result); //$NON-NLS-1$
416
    return result;
417
  }
418
 
419
  /**
420
   * @param aliasName
421
   * @param publicKey
422
   * @param privateKey
423
   * @return the DER encoded Certificate Signing Request.
424
   * @throws IOException
425
   * @throws InvalidKeyException
426
   * @throws SignatureException
427
   */
428
  private byte[] getCSR(X500Principal aliasName, PublicKey publicKey,
429
                        PrivateKey privateKey)
430
      throws IOException, InvalidKeyException, SignatureException
431
  {
432
    DERValue derVersion = new DERValue(DER.INTEGER, BigInteger.ZERO);
433
    DERValue derSubject = new DERReader(aliasName.getEncoded()).read();
434
    DERValue derSubjectPKInfo = new DERReader(publicKey.getEncoded()).read();
435
    byte[] b = nullAttributes ? new byte[] { 0x05, 0x00 } : new byte[0];
436
    DERValue derAttributes = new DERValue(DER.CONSTRUCTED | DER.CONTEXT | 0,
437
                                          b.length, b, null);
438
    ArrayList certRequestInfo = new ArrayList(4);
439
    certRequestInfo.add(derVersion);
440
    certRequestInfo.add(derSubject);
441
    certRequestInfo.add(derSubjectPKInfo);
442
    certRequestInfo.add(derAttributes);
443
    DERValue derCertRequestInfo = new DERValue(DER.CONSTRUCTED | DER.SEQUENCE,
444
                                               certRequestInfo);
445
 
446
    OID sigAlgorithmID = getSignatureAlgorithmOID();
447
    DERValue derSigAlgorithmID = new DERValue(DER.OBJECT_IDENTIFIER,
448
                                              sigAlgorithmID);
449
    ArrayList sigAlgorithm = new ArrayList(2);
450
    sigAlgorithm.add(derSigAlgorithmID);
451
    if (! sigAlgorithmID.equals(Command.SHA1_WITH_DSA)) // it's an RSA-based
452
      sigAlgorithm.add(new DERValue(DER.NULL, null));
453
 
454
    sigAlgorithm.trimToSize();
455
    DERValue derSignatureAlgorithm = new DERValue(DER.CONSTRUCTED | DER.SEQUENCE,
456
                                                  sigAlgorithm);
457
 
458
    signatureAlgorithm.initSign(privateKey);
459
    signatureAlgorithm.update(derCertRequestInfo.getEncoded());
460
    byte[] sigBytes = signatureAlgorithm.sign();
461
    DERValue derSignature = new DERValue(DER.BIT_STRING, new BitString(sigBytes));
462
 
463
    ArrayList csr = new ArrayList(3);
464
    csr.add(derCertRequestInfo);
465
    csr.add(derSignatureAlgorithm);
466
    csr.add(derSignature);
467
    DERValue derCSR = new DERValue(DER.CONSTRUCTED | DER.SEQUENCE, csr);
468
 
469
    ByteArrayOutputStream baos = new ByteArrayOutputStream();
470
    DERWriter.write(baos, derCSR);
471
    byte[] result = baos.toByteArray();
472
 
473
    return result;
474
  }
475
}

powered by: WebSVN 2.1.0

© copyright 1999-2024 OpenCores.org, equivalent to Oliscience, all rights reserved. OpenCores®, registered trademark.