All Downloads are FREE. Search and download functionalities are using the official Maven repository.

com.tencent.kona.sun.security.tools.keytool.CertAndKeyGen Maven / Gradle / Ivy

Go to download

A Java security provider for supporting ShangMi algorithms in public key infrastructure

There is a newer version: 1.0.15
Show newest version
/*
 * Copyright (c) 1996, 2022, Oracle and/or its affiliates. All rights reserved.
 * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
 *
 * This code is free software; you can redistribute it and/or modify it
 * under the terms of the GNU General Public License version 2 only, as
 * published by the Free Software Foundation.  Oracle designates this
 * particular file as subject to the "Classpath" exception as provided
 * by Oracle in the LICENSE file that accompanied this code.
 *
 * This code 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
 * version 2 for more details (a copy is included in the LICENSE file that
 * accompanied this code).
 *
 * You should have received a copy of the GNU General Public License version
 * 2 along with this work; if not, write to the Free Software Foundation,
 * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
 *
 * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
 * or visit www.oracle.com if you need additional information or have any
 * questions.
 */

package com.tencent.kona.sun.security.tools.keytool;

import java.io.IOException;
import java.security.cert.X509Certificate;
import java.security.cert.CertificateException;
import java.security.cert.CertificateEncodingException;
import java.security.*;
import java.security.spec.ECGenParameterSpec;
import java.util.Calendar;
import java.util.Date;
import java.util.GregorianCalendar;
import java.util.TimeZone;

import com.tencent.kona.sun.security.pkcs10.PKCS10;
import com.tencent.kona.sun.security.util.SignatureUtil;
import com.tencent.kona.sun.security.x509.*;

/**
 * Generate a pair of keys, and provide access to them.  This class is
 * provided primarily for ease of use.
 *
 * 

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. * *

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. At this time, this interface * supports initializing with a named group. * *

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 * @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". If set to null, a default * algorithm matching the private key will be chosen after * the first keypair is generated. * @exception NoSuchAlgorithmException on unrecognized algorithms. */ public CertAndKeyGen (String keyType, String sigAlg) throws NoSuchAlgorithmException { keyGen = KeyPairGenerator.getInstance(keyType); this.sigAlg = sigAlg; this.keyType = keyType; } /** * @see #CertAndKeyGen(String, String, String, PrivateKey, X500Name) */ public CertAndKeyGen (String keyType, String sigAlg, String providerName) throws NoSuchAlgorithmException, NoSuchProviderException { this(keyType, sigAlg, providerName, null, null); } /** * Creates a CertAndKeyGen object for a particular key type, * signature algorithm, and provider. The newly generated cert will * be signed by the signer's private key when it is provided. * * @param keyType type of key, e.g. "RSA", "DSA", "X25519", "DH", etc. * @param sigAlg name of the signature algorithm, e.g. "SHA384WithRSA", * "SHA256withDSA", etc. If set to null, a default * algorithm matching the private key or signer's private * key will be chosen after the first keypair is generated. * @param providerName name of the provider * @param signerPrivateKey (optional) signer's private key * @param signerSubjectName (optional) signer's subject name * @exception NoSuchAlgorithmException on unrecognized algorithms. * @exception NoSuchProviderException on unrecognized providers. */ public CertAndKeyGen(String keyType, String sigAlg, String providerName, PrivateKey signerPrivateKey, X500Name signerSubjectName) throws NoSuchAlgorithmException, NoSuchProviderException { if (providerName == null) { keyGen = KeyPairGenerator.getInstance(keyType); } else { try { keyGen = KeyPairGenerator.getInstance(keyType, providerName); } catch (Exception e) { // try first available provider instead keyGen = KeyPairGenerator.getInstance(keyType); } } this.sigAlg = sigAlg; this.keyType = keyType; this.signerPrivateKey = signerPrivateKey; this.signerSubjectName = signerSubjectName; this.signerFlag = signerPrivateKey != null; } /** * 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. */ public void setRandom (SecureRandom generator) { prng = generator; } public void generate(String name) { try { if (prng == null) { prng = new SecureRandom(); } // try { // keyGen.initialize(new NamedParameterSpec(name), prng); // } catch (InvalidAlgorithmParameterException e) { // if (keyType.equalsIgnoreCase("EC")) { // // EC has another NamedParameterSpec // keyGen.initialize(new ECGenParameterSpec(name), prng); // } else { // throw e; // } // } if (keyType.equalsIgnoreCase("EC")) { // EC has another NamedParameterSpec keyGen.initialize(new ECGenParameterSpec(name), prng); } else { throw new UnsupportedOperationException("Only support EC: " + name); } } catch (Exception e) { throw new IllegalArgumentException(e.getMessage(), e); } generateInternal(); } // want "public void generate (X509Certificate)" ... inherit DSA/D-H param public void generate(int keyBits) { if (keyBits != -1) { try { if (prng == null) { prng = new SecureRandom(); } keyGen.initialize(keyBits, prng); } catch (Exception e) { throw new IllegalArgumentException(e.getMessage(), e); } } generateInternal(); } /** * Generates a random public/private key pair. * *

Note that 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. * * @exception IllegalArgumentException if the environment does not * provide X.509 public keys for this signature algorithm. */ private void generateInternal() { KeyPair pair = keyGen.generateKeyPair(); publicKey = pair.getPublic(); privateKey = pair.getPrivate(); // publicKey's format must be X.509 otherwise // the whole CertGen part of this class is broken. if (!"X.509".equalsIgnoreCase(publicKey.getFormat())) { throw new IllegalArgumentException("Public key format is " + publicKey.getFormat() + ", must be X.509"); } if (sigAlg == null) { if (signerFlag) { sigAlg = SignatureUtil.getDefaultSigAlgForKey(signerPrivateKey); if (sigAlg == null) { throw new IllegalArgumentException( "Cannot derive signature algorithm from " + signerPrivateKey.getAlgorithm()); } } else { sigAlg = SignatureUtil.getDefaultSigAlgForKey(privateKey); if (sigAlg == null) { throw new IllegalArgumentException( "Cannot derive signature algorithm from " + privateKey.getAlgorithm()); } } } } /** * Returns the public key of the generated key pair if it is of type * X509Key, or null if the public key is of a different type. * * XXX Note: This behaviour is needed for backwards compatibility. * What this method really should return is the public key of the * generated key pair, regardless of whether it is an instance of * X509Key. Accordingly, the return type of this method * should be PublicKey. */ public X509Key getPublicKey() { if (!(publicKey instanceof X509Key)) { return null; } return (X509Key)publicKey; } /** * Always returns the public key of the generated key pair. Used * by KeyTool only. * * The publicKey is not necessarily to be an instance of * X509Key in some JCA/JCE providers, for example SunPKCS11. */ public PublicKey getPublicKeyAnyway() { return publicKey; } /** * Returns the private key of the generated key pair. * *

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! */ public PrivateKey getPrivateKey () { return privateKey; } /** * Returns a self-signed X.509v3 certificate for the public key. * The certificate is immediately valid. No extensions. * *

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 firstDate the issue time of the certificate * @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, Date firstDate, long validity) throws CertificateException, InvalidKeyException, SignatureException, NoSuchAlgorithmException, NoSuchProviderException { return getSelfCertificate(myname, firstDate, validity, null); } // Like above, plus a CertificateExtensions argument, which can be null. // Create a self-signed certificate, or a certificate that is signed by // a signer when the signer's private key is provided. public X509Certificate getSelfCertificate (X500Name myname, Date firstDate, long validity, CertificateExtensions ext) throws CertificateException, InvalidKeyException, SignatureException, NoSuchAlgorithmException, NoSuchProviderException { X509CertImpl cert; Date lastDate; try { lastDate = new Date (); lastDate.setTime (firstDate.getTime () + validity * 1000); Calendar c = new GregorianCalendar(TimeZone.getTimeZone("UTC")); c.setTime(lastDate); if (c.get(Calendar.YEAR) > 9999) { throw new CertificateException("Validity period ends at calendar year " + c.get(Calendar.YEAR) + " which is greater than 9999"); } CertificateValidity interval = new CertificateValidity(firstDate,lastDate); X509CertInfo info = new X509CertInfo(); // Add all mandatory attributes info.setVersion(new CertificateVersion(CertificateVersion.V3)); if (prng == null) { prng = new SecureRandom(); } info.setSerialNumber(CertificateSerialNumber.newRandom64bit(prng)); info.setSubject(myname); info.setKey(new CertificateX509Key(publicKey)); info.setValidity(interval); if (signerFlag) { // use signer's subject name to set the issuer name info.setIssuer(signerSubjectName); } else { info.setIssuer(myname); } if (ext != null) info.setExtensions(ext); if (signerFlag) { // use signer's private key to sign cert = X509CertImpl.newSigned(info, signerPrivateKey, sigAlg); } else { cert = X509CertImpl.newSigned(info, privateKey, sigAlg); } return cert; } catch (IOException e) { throw new CertificateEncodingException("getSelfCert: " + e.getMessage(), e); } } // Keep the old method public X509Certificate getSelfCertificate (X500Name myname, long validity) throws CertificateException, InvalidKeyException, SignatureException, NoSuchAlgorithmException, NoSuchProviderException { return getSelfCertificate(myname, new Date(), validity); } private SecureRandom prng; private final String keyType; private String sigAlg; private KeyPairGenerator keyGen; private PublicKey publicKey; private PrivateKey privateKey; private boolean signerFlag; private PrivateKey signerPrivateKey; private X500Name signerSubjectName; }





© 2015 - 2024 Weber Informatics LLC | Privacy Policy