diff options
Diffstat (limited to 'pki/base/util/src/netscape/security/x509/CertAndKeyGen.java')
-rw-r--r-- | pki/base/util/src/netscape/security/x509/CertAndKeyGen.java | 299 |
1 files changed, 299 insertions, 0 deletions
diff --git a/pki/base/util/src/netscape/security/x509/CertAndKeyGen.java b/pki/base/util/src/netscape/security/x509/CertAndKeyGen.java new file mode 100644 index 000000000..75d8d4a37 --- /dev/null +++ b/pki/base/util/src/netscape/security/x509/CertAndKeyGen.java @@ -0,0 +1,299 @@ +// --- BEGIN COPYRIGHT BLOCK --- +// This program is free software; you can redistribute it and/or modify +// it under the terms of the GNU General Public License as published by +// the Free Software Foundation; version 2 of the License. +// +// This program is distributed in the hope that it will be useful, +// but WITHOUT ANY WARRANTY; without even the implied warranty of +// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +// GNU General Public License for more details. +// +// You should have received a copy of the GNU General Public License along +// with this program; if not, write to the Free Software Foundation, Inc., +// 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. +// +// (C) 2007 Red Hat, Inc. +// All rights reserved. +// --- END COPYRIGHT BLOCK --- +package netscape.security.x509; + +import java.io.IOException; +import java.security.cert.X509Certificate; +import java.security.cert.CertificateException; +import java.security.cert.CertificateEncodingException; +import java.security.*; +import java.util.Date; + +import netscape.security.util.BigInt; +import netscape.security.pkcs.PKCS10; + + +/** + * Generate a pair of keys, and provide access to them. This class is + * provided primarily for ease of use. + * + * <P>This provides some simple certificate management functionality. + * Specifically, it allows you to create self-signed X.509 certificates + * as well as PKCS 10 based certificate signing requests. + * + * <P>Keys for some public key signature algorithms have algorithm + * parameters, such as DSS/DSA. Some sites' Certificate Authorities + * adopt fixed algorithm parameters, which speeds up some operations + * including key generation and signing. <em>At this time, this interface + * does not provide a way to provide such algorithm parameters, e.g. + * by providing the CA certificate which includes those parameters.</em> + * + * <P>Also, note that at this time only signature-capable keys may be + * acquired through this interface. Diffie-Hellman keys, used for secure + * key exchange, may be supported later. + * + * @author David Brownell + * @author Hemma Prafullchandra + * @version 1.44 + * @see PKCS10 + * @see X509CertImpl + */ +public final class CertAndKeyGen { + /** + * Creates a CertAndKeyGen object for a particular key type + * and signature algorithm. + * + * @param keyType type of key, e.g. "RSA", "DSA" + * @param sigAlg name of the signature algorithm, e.g. "MD5WithRSA", + * "MD2WithRSA", "SHAwithDSA". + * @exception NoSuchAlgorithmException on unrecognized algorithms. + */ + public CertAndKeyGen (String keyType, String sigAlg) + throws NoSuchAlgorithmException + { + keyGen = KeyPairGenerator.getInstance(keyType); + this.sigAlg = sigAlg; + } + + /** + * Sets the source of random numbers used when generating keys. + * If you do not provide one, a system default facility is used. + * You may wish to provide your own source of random numbers + * to get a reproducible sequence of keys and signatures, or + * because you may be able to take advantage of strong sources + * of randomness/entropy in your environment. + * + * @deprecated All random numbers come from PKCS #11 now. + */ + public void setRandom (SecureRandom generator) + { + } + + // want "public void generate (X509Certificate)" ... inherit DSA/D-H param + + /** + * Generates a random public/private key pair, with a given key + * size. Different algorithms provide different degrees of security + * for the same key size, because of the "work factor" involved in + * brute force attacks. As computers become faster, it becomes + * easier to perform such attacks. Small keys are to be avoided. + * + * <P>Note that not all values of "keyBits" are valid for all + * algorithms, and not all public key algorithms are currently + * supported for use in X.509 certificates. If the algorithm + * you specified does not produce X.509 compatible keys, an + * invalid key exception is thrown. + * + * @param keyBits the number of bits in the keys. + * @exception InvalidKeyException if the environment does not + * provide X.509 public keys for this signature algorithm. + */ + public void generate (int keyBits) + throws InvalidKeyException + { + KeyPair pair; + + try { + keyGen.initialize (keyBits); + pair = keyGen.generateKeyPair (); + + } catch (Exception e) { + throw new IllegalArgumentException (e.getMessage ()); + } + + PublicKey publicKey = pair.getPublic(); + + if (publicKey instanceof X509Key) { + this.publicKey = (X509Key) publicKey; + + } else { + throw new InvalidKeyException ("public key " + publicKey + + " not an X509Key."); + } + privateKey = pair.getPrivate (); + } + + + /** + * Returns the public key of the generated key pair. + */ + public X509Key getPublicKey () + { + return publicKey; + } + + + /** + * Returns the private key of the generated key pair. + * + * <P><STRONG><em>Be extremely careful when handling private keys. + * When private keys are not kept secret, they lose their ability + * to securely authenticate specific entities ... that is a huge + * security risk!</em></STRONG> + */ + public PrivateKey getPrivateKey () + { + return privateKey; + } + + + /** + * Returns a self-signed X.509v1 certificate for the public key. + * The certificate is immediately valid. + * + * <P>Such certificates normally are used to identify a "Certificate + * Authority" (CA). Accordingly, they will not always be accepted by + * other parties. However, such certificates are also useful when + * you are bootstrapping your security infrastructure, or deploying + * system prototypes. + * + * @deprecated Use the new <a href = + * "#getSelfCertificate(netscape.security.x509.X500Name, long)"> + * + * @param myname X.500 name of the subject (who is also the issuer) + * @param validity how long the certificate should be valid, in seconds + */ + public X509Cert getSelfCert (X500Name myname, long validity) + throws InvalidKeyException, SignatureException, NoSuchAlgorithmException + { + X509Certificate cert; + + try { + cert = getSelfCertificate(myname, validity); + return new X509Cert(cert.getEncoded()); + } catch (CertificateException e) { + throw new SignatureException(e.getMessage()); + } catch (NoSuchProviderException e) { + throw new NoSuchAlgorithmException(e.getMessage()); + } catch (IOException e) { + throw new SignatureException(e.getMessage()); + } + } + + + /** + * Returns a self-signed X.509v3 certificate for the public key. + * The certificate is immediately valid. No extensions. + * + * <P>Such certificates normally are used to identify a "Certificate + * Authority" (CA). Accordingly, they will not always be accepted by + * other parties. However, such certificates are also useful when + * you are bootstrapping your security infrastructure, or deploying + * system prototypes. + * + * @param myname X.500 name of the subject (who is also the issuer) + * @param validity how long the certificate should be valid, in seconds + * @exception CertificateException on certificate handling errors. + * @exception InvalidKeyException on key handling errors. + * @exception SignatureException on signature handling errors. + * @exception NoSuchAlgorithmException on unrecognized algorithms. + * @exception NoSuchProviderException on unrecognized providers. + */ + public X509Certificate getSelfCertificate (X500Name myname, long validity) + throws CertificateException, InvalidKeyException, SignatureException, + NoSuchAlgorithmException, NoSuchProviderException + { + X500Signer issuer; + X509CertImpl cert; + Date firstDate, lastDate; + + try { + issuer = getSigner (myname); + + firstDate = new Date (); + lastDate = new Date (); + lastDate.setTime (lastDate.getTime () + validity * 1000); + + CertificateValidity interval = + new CertificateValidity(firstDate,lastDate); + + X509CertInfo info = new X509CertInfo(); + // Add all mandatory attributes + info.set(X509CertInfo.VERSION, + new CertificateVersion(CertificateVersion.V1)); + info.set(X509CertInfo.SERIAL_NUMBER, + new CertificateSerialNumber((int)(firstDate.getTime()/1000))); + AlgorithmId algID = issuer.getAlgorithmId(); + info.set(X509CertInfo.ALGORITHM_ID, + new CertificateAlgorithmId(algID)); + info.set(X509CertInfo.SUBJECT, new CertificateSubjectName(myname)); + info.set(X509CertInfo.KEY, new CertificateX509Key(publicKey)); + info.set(X509CertInfo.VALIDITY, interval); + info.set(X509CertInfo.ISSUER, + new CertificateIssuerName(issuer.getSigner())); + + cert = new X509CertImpl(info); + cert.sign(privateKey, algID.getName()); + + return (X509Certificate)cert; + + } catch (IOException e) { + throw new CertificateEncodingException("getSelfCert: " + + e.getMessage()); + } + } + + /** + * Returns a PKCS #10 certificate request. The caller uses either + * <code>PKCS10.print</code> or <code>PKCS10.toByteArray</code> + * operations on the result, to get the request in an appropriate + * transmission format. + * + * <P>PKCS #10 certificate requests are sent, along with some proof + * of identity, to Certificate Authorities (CAs) which then issue + * X.509 public key certificates. + * + * @param myname X.500 name of the subject + * @exception InvalidKeyException on key handling errors. + * @exception SignatureException on signature handling errors. + */ + public PKCS10 getCertRequest (X500Name myname) + throws InvalidKeyException, SignatureException + { + PKCS10 req = new PKCS10 (publicKey); + + try { + req.encodeAndSign (getSigner (myname)); + + } catch (CertificateException e) { + throw new SignatureException (sigAlg + " CertificateException"); + + } catch (IOException e) { + throw new SignatureException (sigAlg + " IOException"); + + } catch (NoSuchAlgorithmException e) { + // "can't happen" + throw new SignatureException (sigAlg + " unavailable?"); + } + return req; + } + + private X500Signer getSigner (X500Name me) + throws InvalidKeyException, NoSuchAlgorithmException + { + Signature signature = Signature.getInstance(sigAlg); + + signature.initSign (privateKey); + return new X500Signer (signature, me); + } + + private String sigAlg; + private KeyPairGenerator keyGen; + private X509Key publicKey; + private PrivateKey privateKey; +} |