Save This Page
Home » openjdk-7 » sun.security » x509 » [javadoc | source]
    1   /*
    2    * Copyright (c) 1996, 2009, Oracle and/or its affiliates. All rights reserved.
    3    * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
    4    *
    5    * This code is free software; you can redistribute it and/or modify it
    6    * under the terms of the GNU General Public License version 2 only, as
    7    * published by the Free Software Foundation.  Oracle designates this
    8    * particular file as subject to the "Classpath" exception as provided
    9    * by Oracle in the LICENSE file that accompanied this code.
   10    *
   11    * This code is distributed in the hope that it will be useful, but WITHOUT
   12    * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
   13    * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
   14    * version 2 for more details (a copy is included in the LICENSE file that
   15    * accompanied this code).
   16    *
   17    * You should have received a copy of the GNU General Public License version
   18    * 2 along with this work; if not, write to the Free Software Foundation,
   19    * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
   20    *
   21    * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
   22    * or visit www.oracle.com if you need additional information or have any
   23    * questions.
   24    */
   25   
   26   package sun.security.x509;
   27   
   28   import java.io.IOException;
   29   import java.security.cert.X509Certificate;
   30   import java.security.cert.CertificateException;
   31   import java.security.cert.CertificateEncodingException;
   32   import java.security;
   33   import java.util.Date;
   34   
   35   import sun.security.pkcs.PKCS10;
   36   
   37   
   38   /**
   39    * Generate a pair of keys, and provide access to them.  This class is
   40    * provided primarily for ease of use.
   41    *
   42    * <P>This provides some simple certificate management functionality.
   43    * Specifically, it allows you to create self-signed X.509 certificates
   44    * as well as PKCS 10 based certificate signing requests.
   45    *
   46    * <P>Keys for some public key signature algorithms have algorithm
   47    * parameters, such as DSS/DSA.  Some sites' Certificate Authorities
   48    * adopt fixed algorithm parameters, which speeds up some operations
   49    * including key generation and signing.  <em>At this time, this interface
   50    * does not provide a way to provide such algorithm parameters, e.g.
   51    * by providing the CA certificate which includes those parameters.</em>
   52    *
   53    * <P>Also, note that at this time only signature-capable keys may be
   54    * acquired through this interface.  Diffie-Hellman keys, used for secure
   55    * key exchange, may be supported later.
   56    *
   57    * @author David Brownell
   58    * @author Hemma Prafullchandra
   59    * @see PKCS10
   60    * @see X509CertImpl
   61    */
   62   public final class CertAndKeyGen {
   63       /**
   64        * Creates a CertAndKeyGen object for a particular key type
   65        * and signature algorithm.
   66        *
   67        * @param keyType type of key, e.g. "RSA", "DSA"
   68        * @param sigAlg name of the signature algorithm, e.g. "MD5WithRSA",
   69        *          "MD2WithRSA", "SHAwithDSA".
   70        * @exception NoSuchAlgorithmException on unrecognized algorithms.
   71        */
   72       public CertAndKeyGen (String keyType, String sigAlg)
   73       throws NoSuchAlgorithmException
   74       {
   75           keyGen = KeyPairGenerator.getInstance(keyType);
   76           this.sigAlg = sigAlg;
   77       }
   78   
   79       /**
   80        * Creates a CertAndKeyGen object for a particular key type,
   81        * signature algorithm, and provider.
   82        *
   83        * @param keyType type of key, e.g. "RSA", "DSA"
   84        * @param sigAlg name of the signature algorithm, e.g. "MD5WithRSA",
   85        *          "MD2WithRSA", "SHAwithDSA".
   86        * @param providerName name of the provider
   87        * @exception NoSuchAlgorithmException on unrecognized algorithms.
   88        * @exception NoSuchProviderException on unrecognized providers.
   89        */
   90       public CertAndKeyGen (String keyType, String sigAlg, String providerName)
   91       throws NoSuchAlgorithmException, NoSuchProviderException
   92       {
   93           if (providerName == null) {
   94               keyGen = KeyPairGenerator.getInstance(keyType);
   95           } else {
   96               try {
   97                   keyGen = KeyPairGenerator.getInstance(keyType, providerName);
   98               } catch (Exception e) {
   99                   // try first available provider instead
  100                   keyGen = KeyPairGenerator.getInstance(keyType);
  101               }
  102           }
  103           this.sigAlg = sigAlg;
  104       }
  105   
  106       /**
  107        * Sets the source of random numbers used when generating keys.
  108        * If you do not provide one, a system default facility is used.
  109        * You may wish to provide your own source of random numbers
  110        * to get a reproducible sequence of keys and signatures, or
  111        * because you may be able to take advantage of strong sources
  112        * of randomness/entropy in your environment.
  113        */
  114       public void         setRandom (SecureRandom generator)
  115       {
  116           prng = generator;
  117       }
  118   
  119       // want "public void generate (X509Certificate)" ... inherit DSA/D-H param
  120   
  121       /**
  122        * Generates a random public/private key pair, with a given key
  123        * size.  Different algorithms provide different degrees of security
  124        * for the same key size, because of the "work factor" involved in
  125        * brute force attacks.  As computers become faster, it becomes
  126        * easier to perform such attacks.  Small keys are to be avoided.
  127        *
  128        * <P>Note that not all values of "keyBits" are valid for all
  129        * algorithms, and not all public key algorithms are currently
  130        * supported for use in X.509 certificates.  If the algorithm
  131        * you specified does not produce X.509 compatible keys, an
  132        * invalid key exception is thrown.
  133        *
  134        * @param keyBits the number of bits in the keys.
  135        * @exception InvalidKeyException if the environment does not
  136        *  provide X.509 public keys for this signature algorithm.
  137        */
  138       public void generate (int keyBits)
  139       throws InvalidKeyException
  140       {
  141           KeyPair pair;
  142   
  143           try {
  144               if (prng == null) {
  145                   prng = new SecureRandom();
  146               }
  147               keyGen.initialize(keyBits, prng);
  148               pair = keyGen.generateKeyPair();
  149   
  150           } catch (Exception e) {
  151               throw new IllegalArgumentException(e.getMessage());
  152           }
  153   
  154           publicKey = pair.getPublic();
  155           privateKey = pair.getPrivate();
  156       }
  157   
  158   
  159       /**
  160        * Returns the public key of the generated key pair if it is of type
  161        * <code>X509Key</code>, or null if the public key is of a different type.
  162        *
  163        * XXX Note: This behaviour is needed for backwards compatibility.
  164        * What this method really should return is the public key of the
  165        * generated key pair, regardless of whether or not it is an instance of
  166        * <code>X509Key</code>. Accordingly, the return type of this method
  167        * should be <code>PublicKey</code>.
  168        */
  169       public X509Key getPublicKey()
  170       {
  171           if (!(publicKey instanceof X509Key)) {
  172               return null;
  173           }
  174           return (X509Key)publicKey;
  175       }
  176   
  177   
  178       /**
  179        * Returns the private key of the generated key pair.
  180        *
  181        * <P><STRONG><em>Be extremely careful when handling private keys.
  182        * When private keys are not kept secret, they lose their ability
  183        * to securely authenticate specific entities ... that is a huge
  184        * security risk!</em></STRONG>
  185        */
  186       public PrivateKey getPrivateKey ()
  187       {
  188           return privateKey;
  189       }
  190   
  191   
  192       /**
  193        * Returns a self-signed X.509v3 certificate for the public key.
  194        * The certificate is immediately valid. No extensions.
  195        *
  196        * <P>Such certificates normally are used to identify a "Certificate
  197        * Authority" (CA).  Accordingly, they will not always be accepted by
  198        * other parties.  However, such certificates are also useful when
  199        * you are bootstrapping your security infrastructure, or deploying
  200        * system prototypes.
  201        *
  202        * @param myname X.500 name of the subject (who is also the issuer)
  203        * @param firstDate the issue time of the certificate
  204        * @param validity how long the certificate should be valid, in seconds
  205        * @exception CertificateException on certificate handling errors.
  206        * @exception InvalidKeyException on key handling errors.
  207        * @exception SignatureException on signature handling errors.
  208        * @exception NoSuchAlgorithmException on unrecognized algorithms.
  209        * @exception NoSuchProviderException on unrecognized providers.
  210        */
  211       public X509Certificate getSelfCertificate (
  212               X500Name myname, Date firstDate, long validity)
  213       throws CertificateException, InvalidKeyException, SignatureException,
  214           NoSuchAlgorithmException, NoSuchProviderException
  215       {
  216           X509CertImpl    cert;
  217           Date            lastDate;
  218   
  219           try {
  220               lastDate = new Date ();
  221               lastDate.setTime (firstDate.getTime () + validity * 1000);
  222   
  223               CertificateValidity interval =
  224                                      new CertificateValidity(firstDate,lastDate);
  225   
  226               X509CertInfo info = new X509CertInfo();
  227               // Add all mandatory attributes
  228               info.set(X509CertInfo.VERSION,
  229                        new CertificateVersion(CertificateVersion.V3));
  230               info.set(X509CertInfo.SERIAL_NUMBER, new CertificateSerialNumber(
  231                       new java.util.Random().nextInt() & 0x7fffffff));
  232               AlgorithmId algID = AlgorithmId.getAlgorithmId(sigAlg);
  233               info.set(X509CertInfo.ALGORITHM_ID,
  234                        new CertificateAlgorithmId(algID));
  235               info.set(X509CertInfo.SUBJECT, new CertificateSubjectName(myname));
  236               info.set(X509CertInfo.KEY, new CertificateX509Key(publicKey));
  237               info.set(X509CertInfo.VALIDITY, interval);
  238               info.set(X509CertInfo.ISSUER, new CertificateIssuerName(myname));
  239   
  240               cert = new X509CertImpl(info);
  241               cert.sign(privateKey, this.sigAlg);
  242   
  243               return (X509Certificate)cert;
  244   
  245           } catch (IOException e) {
  246                throw new CertificateEncodingException("getSelfCert: " +
  247                                                       e.getMessage());
  248           }
  249       }
  250   
  251       // Keep the old method
  252       public X509Certificate getSelfCertificate (X500Name myname, long validity)
  253       throws CertificateException, InvalidKeyException, SignatureException,
  254           NoSuchAlgorithmException, NoSuchProviderException
  255       {
  256           return getSelfCertificate(myname, new Date(), validity);
  257       }
  258   
  259       /**
  260        * Returns a PKCS #10 certificate request.  The caller uses either
  261        * <code>PKCS10.print</code> or <code>PKCS10.toByteArray</code>
  262        * operations on the result, to get the request in an appropriate
  263        * transmission format.
  264        *
  265        * <P>PKCS #10 certificate requests are sent, along with some proof
  266        * of identity, to Certificate Authorities (CAs) which then issue
  267        * X.509 public key certificates.
  268        *
  269        * @param myname X.500 name of the subject
  270        * @exception InvalidKeyException on key handling errors.
  271        * @exception SignatureException on signature handling errors.
  272        */
  273       public PKCS10 getCertRequest (X500Name myname)
  274       throws InvalidKeyException, SignatureException
  275       {
  276           PKCS10  req = new PKCS10 (publicKey);
  277   
  278           try {
  279               Signature signature = Signature.getInstance(sigAlg);
  280               signature.initSign (privateKey);
  281               req.encodeAndSign(myname, signature);
  282   
  283           } catch (CertificateException e) {
  284               throw new SignatureException (sigAlg + " CertificateException");
  285   
  286           } catch (IOException e) {
  287               throw new SignatureException (sigAlg + " IOException");
  288   
  289           } catch (NoSuchAlgorithmException e) {
  290               // "can't happen"
  291               throw new SignatureException (sigAlg + " unavailable?");
  292           }
  293           return req;
  294       }
  295   
  296       private SecureRandom        prng;
  297       private String              sigAlg;
  298       private KeyPairGenerator    keyGen;
  299       private PublicKey           publicKey;
  300       private PrivateKey          privateKey;
  301   }

Save This Page
Home » openjdk-7 » sun.security » x509 » [javadoc | source]