| | |
| | | * CDDL HEADER END |
| | | * |
| | | * |
| | | * Copyright 2010 Sun Microsystems, Inc. |
| | | * Copyright 2009-2010 Sun Microsystems, Inc. |
| | | */ |
| | | |
| | | package org.opends.server.util; |
| | |
| | | import java.security.KeyStoreException; |
| | | import java.security.KeyStore; |
| | | import java.security.PrivateKey; |
| | | import java.security.PublicKey; |
| | | import java.security.Signature; |
| | | import java.security.cert.Certificate; |
| | | import java.security.cert.CertificateFactory; |
| | | import java.security.cert.X509Certificate; |
| | | import java.io.File; |
| | | import java.io.FileInputStream; |
| | | import java.io.FileOutputStream; |
| | | import java.io.InputStream; |
| | | import java.io.PrintStream; |
| | | import java.lang.reflect.Constructor; |
| | | import java.lang.reflect.Method; |
| | | import org.opends.messages.Message; |
| | | import static org.opends.messages.UtilityMessages.*; |
| | | |
| | | |
| | | /** |
| | | * Provides a wrapper class that collects all of the JVM vendor |
| | | * and JDK version specific code in a single place. |
| | |
| | | //Prefix that determines which security package to use. |
| | | private static String pkgPrefix; |
| | | |
| | | //IBM security package doesn't appear to support PCKS10, this flags turns |
| | | //off support for that. |
| | | private static boolean certReqAllowed; |
| | | |
| | | //The two security package prefixes (IBM and SUN). |
| | | private static final String IBM_SEC = "com.ibm.security"; |
| | | private static final String SUN_SEC = "sun.security"; |
| | |
| | | if(vendor.startsWith("IBM")) |
| | | { |
| | | pkgPrefix = IBM_SEC; |
| | | certReqAllowed = false; |
| | | if(ver.startsWith("1.5")) |
| | | { |
| | | IMPL = new IBM5PlatformIMPL(); |
| | | } |
| | | else |
| | | { |
| | | IMPL = new JDK6PlatformIMPL(); |
| | | IMPL = new DefaultPlatformIMPL(); |
| | | } |
| | | } |
| | | else |
| | | { |
| | | pkgPrefix = SUN_SEC; |
| | | certReqAllowed = true; |
| | | if(ver.startsWith("1.5")) |
| | | { |
| | | IMPL = new Sun5PlatformIMPL(); |
| | | } |
| | | else if(ver.startsWith("1.6")) |
| | | { |
| | | IMPL = new JDK6PlatformIMPL(); |
| | | } |
| | | else |
| | | { |
| | | IMPL = new DefaultPlatformIMPL(); |
| | |
| | | //Key size, key algorithm and signature algorithms used. |
| | | private static final int KEY_SIZE = 1024; |
| | | private static final String KEY_ALGORITHM = "rsa"; |
| | | static final String SIG_ALGORITHM = "SHA1WithRSA"; |
| | | private static final String SIG_ALGORITHM = "SHA1WithRSA"; |
| | | |
| | | //Time values used in validity calculations. |
| | | private static final int SEC_IN_DAY = 24 * 60 * 60; |
| | | static final int DEFAULT_VALIDITY = 90 * SEC_IN_DAY; |
| | | |
| | | //These two are used to build certificate request files. |
| | | static final String TMPFILE_PREFIX = "CertificateManager-"; |
| | | static final String TMPFILE_EXT = ".csr"; |
| | | |
| | | //Methods pulled from the classes. |
| | | static final String ENCODE_SIGN_METHOD = "encodeAndSign"; |
| | | private static final String GENERATE_METHOD = "generate"; |
| | | private static final String GET_PRIVATE_KEY_METHOD = "getPrivateKey"; |
| | | private static final String GET_SELFSIGNED_CERT_METHOD = |
| | | "getSelfCertificate"; |
| | | static final String PRINT_METHOD = "print"; |
| | | |
| | | //Classes needed to manage certificates. |
| | | static Class<?> certKeyGenClass, X500NameClass; |
| | | static Class<?> PKCS10Class; |
| | | private static Class<?> certKeyGenClass, X500NameClass; |
| | | |
| | | //Constructors for each of the above classes. |
| | | static Constructor<?> certKeyGenCons, X500NameCons, pkcs10Cons; |
| | | private static Constructor<?> certKeyGenCons, X500NameCons; |
| | | |
| | | static { |
| | | String x509pkg = pkgPrefix + ".x509"; |
| | | String pkcs10Pkg = pkgPrefix + ".pkcs"; |
| | | String certAndKeyGen= x509pkg + ".CertAndKeyGen"; |
| | | String X500Name = x509pkg + ".X500Name"; |
| | | try { |
| | | certKeyGenClass = Class.forName(certAndKeyGen); |
| | | X500NameClass = Class.forName(X500Name); |
| | | if(certReqAllowed) { |
| | | String pkcs10 = pkcs10Pkg + ".PKCS10"; |
| | | PKCS10Class = Class.forName(pkcs10); |
| | | pkcs10Cons = PKCS10Class.getConstructor(PublicKey.class); |
| | | } |
| | | certKeyGenCons = |
| | | certKeyGenClass.getConstructor(String.class, String.class); |
| | | X500NameCons = X500NameClass.getConstructor(String.class); |
| | |
| | | } |
| | | } |
| | | |
| | | protected PlatformIMPL() {} |
| | | |
| | | public abstract File generateCertificateRequest(KeyStore ks, |
| | | String ksType, String ksPath, String alias, |
| | | char[] pwd, String dn) throws KeyStoreException; |
| | | protected PlatformIMPL() {} |
| | | |
| | | |
| | | /** |
| | |
| | | } |
| | | } |
| | | |
| | | |
| | | /** |
| | | * Add the certificate in the specified path to the specified keystore, |
| | | * creating the keystore using the specified type and path if it the |
| | |
| | | } |
| | | } |
| | | |
| | | |
| | | /** |
| | | * Generate a self-signed certificate using the specified alias, dn |
| | | * string and validity period. If the keystore does not exist, create it |
| | |
| | | return ks; |
| | | } |
| | | |
| | | |
| | | /** |
| | | * Generate a x509 certificate from the input stream. Verification is |
| | | * done only if it is self-signed. |
| | |
| | | private void trustedCert(String alias, CertificateFactory cf, |
| | | KeyStore ks, InputStream in) throws KeyStoreException { |
| | | try { |
| | | if (ks.containsAlias(alias) == true) { |
| | | if (ks.containsAlias(alias)) { |
| | | Message msg = ERR_CERTMGR_ALIAS_ALREADY_EXISTS.get(alias); |
| | | throw new KeyStoreException(msg.toString()); |
| | | } |
| | |
| | | } |
| | | } |
| | | |
| | | |
| | | /** |
| | | * Check that the issuer and subject DNs match. |
| | | * |
| | |
| | | } |
| | | |
| | | /** |
| | | * Returns the private key associated with specified alias and keystore. |
| | | * The keystore was already checked for existance. |
| | | * |
| | | * @param ks The keystore to get the private key from, it must exist. |
| | | * @param alias The alias to get the private key of. |
| | | * @param pwd The password used to get the key from the keystore. |
| | | * @return The private key of related to the alias. |
| | | * |
| | | * @throws KeyStoreException If the alias is not in the keystore, the |
| | | * entry related to the alias is not of |
| | | */ |
| | | PrivateKey getPrivateKey(KeyStore ks, String alias, char[] pwd) |
| | | throws KeyStoreException { |
| | | PrivateKey key = null; |
| | | try { |
| | | if(!ks.containsAlias(alias)) { |
| | | Message msg = ERR_CERTMGR_ALIAS_DOES_NOT_EXIST.get(alias); |
| | | throw new KeyStoreException(msg.toString()); |
| | | } |
| | | if(!ks.entryInstanceOf(alias, KeyStore.PrivateKeyEntry.class) && |
| | | !ks.entryInstanceOf(alias, KeyStore.SecretKeyEntry.class)) { |
| | | Message msg = |
| | | ERR_CERTMGR_ALIAS_INVALID_ENTRY_TYPE.get(alias); |
| | | throw new KeyStoreException(msg.toString()); |
| | | } |
| | | key = (PrivateKey)ks.getKey(alias, pwd); |
| | | } catch (Exception e) { |
| | | Message msg = |
| | | ERR_CERTMGR_GET_KEY.get(alias,e.getMessage()); |
| | | throw new KeyStoreException(msg.toString()); |
| | | } |
| | | return key; |
| | | } |
| | | |
| | | /** |
| | | * Normalize the data in the specified buffer. |
| | | * |
| | | * @param buffer The buffer to normalize. |
| | |
| | | |
| | | |
| | | /** |
| | | * Generate a certificate request using the specified parameters. |
| | | * |
| | | * @param ks The keystore to use in the request creation. |
| | | * @param ksType The keystore type. |
| | | * @param ksPath The path to the keystore. |
| | | * @param alias The alias to use in the request generation. |
| | | * @param pwd The keystore password to use. |
| | | * @param dn A dn string to use as the certificate subject. |
| | | * @return A file object pointing at the created certificate request. |
| | | * |
| | | * @throws KeyStoreException If the certificate request failed. |
| | | */ |
| | | public static File generateCertificateRequest(KeyStore ks, String ksType, |
| | | String ksPath, String alias, char[] pwd, String dn) |
| | | throws KeyStoreException { |
| | | return IMPL.generateCertificateRequest(ks, ksType, ksPath, alias, |
| | | pwd, dn); |
| | | } |
| | | |
| | | |
| | | /** |
| | | * Generate a self-signed certificate using the specified alias, dn |
| | | * string and validity period. If the keystore does not exist, it will be |
| | | * created using the specified keystore type and path. |
| | |
| | | //Normalized form method. |
| | | private static final Object FORM_NFKC; |
| | | |
| | | private static Class<?> X500SignerClass; |
| | | private static Constructor<?> X500SignerCons; |
| | | |
| | | static { |
| | | Method normalize = null; |
| | | Object formNFKC = null; |
| | | String x509pkg = pkgPrefix + ".x509"; |
| | | String X500Signer = x509pkg + ".X500Signer"; |
| | | try { |
| | | Class<?> normalizer = Class.forName("sun.text.Normalizer"); |
| | | formNFKC = normalizer.getField("DECOMP_COMPAT").get(null); |
| | | Class<?> normalizerForm = Class.forName("sun.text.Normalizer$Mode"); |
| | | normalize = normalizer.getMethod("normalize", String.class, |
| | | normalizerForm, Integer.TYPE); |
| | | X500SignerClass = Class.forName(X500Signer); |
| | | X500SignerCons = X500SignerClass.getConstructor(Signature.class, |
| | | X500NameClass); |
| | | } |
| | | catch (ClassNotFoundException e) { |
| | | Message msg = ERR_CERTMGR_CLASS_NOT_FOUND.get(e.getMessage()); |
| | | throw new ExceptionInInitializerError(msg.toString()); |
| | | } catch (SecurityException e) { |
| | | Message msg = ERR_CERTMGR_SECURITY.get(e.getMessage()); |
| | | throw new ExceptionInInitializerError(msg.toString()); |
| | | } catch (NoSuchMethodException e) { |
| | | Message msg = ERR_CERTMGR_NO_METHOD.get(e.getMessage()); |
| | | throw new ExceptionInInitializerError(msg.toString()); |
| | | } |
| | | catch (Exception ex) { |
| | | // Do not use Normalizer. The values are already set to null. |
| | |
| | | //Don't do anything. buffer should be used. |
| | | } |
| | | } |
| | | |
| | | /** |
| | | * Generate a certificate request. Note that this methods checks if |
| | | * the certificate request generation is allowed and throws an |
| | | * exception if it isn't supported. Some vendors JDKs aren't compatible |
| | | * with Sun's certificate request generation classes so they aren't |
| | | * supported. Note this method uses the X500Signer class which has been |
| | | * deprecated in JDK 1.7. |
| | | * |
| | | * @param ks The keystore to use in the request creation. |
| | | * @param ksType The keystore type. |
| | | * @param ksPath The path to the keystore. |
| | | * @param alias The alias to use in the request generation. |
| | | * @param pwd The keystore password to use. |
| | | * @param dn A dn string to use as the certificate subject. |
| | | * |
| | | * @return A file object pointing at the created certificate request. |
| | | * @throws KeyStoreException If the certificate request failed. |
| | | */ |
| | | public File |
| | | generateCertificateRequest(KeyStore ks, String ksType, String ksPath, |
| | | String alias, char[] pwd, String dn) throws KeyStoreException { |
| | | if(!certReqAllowed) { |
| | | String vendor = System.getProperty("java.vendor"); |
| | | Message msg = |
| | | ERR_CERTMGR_CERT_SIGN_REQ_NOT_SUPPORTED.get(vendor); |
| | | throw new KeyStoreException(msg.toString()); |
| | | } |
| | | KeyStore keyStore = generateSelfSignedCertificate(ks, ksType, ksPath, |
| | | alias, pwd, dn, DEFAULT_VALIDITY); |
| | | File csrFile; |
| | | try { |
| | | csrFile = File.createTempFile(TMPFILE_PREFIX, TMPFILE_EXT); |
| | | csrFile.deleteOnExit(); |
| | | PrintStream printStream = |
| | | new PrintStream(new FileOutputStream(csrFile.getAbsolutePath())); |
| | | if(keyStore == null) { |
| | | Message msg = ERR_CERTMGR_KEYSTORE_NONEXISTANT.get(); |
| | | throw new KeyStoreException(msg.toString()); |
| | | } |
| | | PrivateKey privateKey = getPrivateKey(keyStore, alias, pwd); |
| | | if(privateKey == null) { |
| | | Message msg = ERR_CERTMGR_PRIVATE_KEY.get(alias); |
| | | throw new KeyStoreException(msg.toString()); |
| | | } |
| | | Certificate cert = keyStore.getCertificate(alias); |
| | | if(cert == null) { |
| | | Message msg = ERR_CERTMGR_ALIAS_NO_CERTIFICATE.get(alias); |
| | | throw new KeyStoreException(msg.toString()); |
| | | } |
| | | Signature signature = Signature.getInstance(SIG_ALGORITHM); |
| | | signature.initSign(privateKey); |
| | | Object request = pkcs10Cons.newInstance(cert.getPublicKey()); |
| | | Object subject = X500NameCons.newInstance(dn); |
| | | Object signer = |
| | | X500SignerCons.newInstance(signature, subject); |
| | | Method encodeAndSign = |
| | | PKCS10Class.getMethod(ENCODE_SIGN_METHOD, X500SignerClass); |
| | | Method print = |
| | | PKCS10Class.getMethod(PRINT_METHOD, PrintStream.class); |
| | | encodeAndSign.invoke(request, signer); |
| | | print.invoke(request, printStream); |
| | | printStream.close(); |
| | | } catch (Exception e) { |
| | | Message msg = ERR_CERTMGR_CERT_REQUEST.get(alias,e.getMessage()); |
| | | throw new KeyStoreException(msg.toString()); |
| | | } |
| | | return csrFile; |
| | | } |
| | | |
| | | } |
| | | |
| | | /** |
| | |
| | | //Don't do anything. buffer should be used. |
| | | } |
| | | } |
| | | |
| | | /** |
| | | * Generate a certificate request. Note that this methods checks if |
| | | * the certificate request generation is allowed and throws an |
| | | * exception if it isn't supported. Some vendors JDKs aren't compatible |
| | | * with Sun's certificate request generation classes so they aren't |
| | | * supported. |
| | | * |
| | | * @param ks The keystore to use in the request creation. |
| | | * @param ksType The keystore type. |
| | | * @param ksPath The path to the keystore. |
| | | * @param alias The alias to use in the request generation. |
| | | * @param pwd The keystore password to use. |
| | | * @param dn A dn string to use as the certificate subject. |
| | | * |
| | | * @return A file object pointing at the created certificate request. |
| | | * @throws KeyStoreException If the certificate request failed. |
| | | */ |
| | | public File |
| | | generateCertificateRequest(KeyStore ks, String ksType, String ksPath, |
| | | String alias, char[] pwd, String dn) throws KeyStoreException { |
| | | if(!certReqAllowed) { |
| | | String vendor = System.getProperty("java.vendor"); |
| | | Message msg = |
| | | ERR_CERTMGR_CERT_SIGN_REQ_NOT_SUPPORTED.get(vendor); |
| | | throw new KeyStoreException(msg.toString()); |
| | | } |
| | | KeyStore keyStore = generateSelfSignedCertificate(ks, ksType, ksPath, |
| | | alias, pwd, dn, DEFAULT_VALIDITY); |
| | | File csrFile; |
| | | try { |
| | | csrFile = File.createTempFile(TMPFILE_PREFIX, TMPFILE_EXT); |
| | | csrFile.deleteOnExit(); |
| | | PrintStream printStream = |
| | | new PrintStream(new FileOutputStream(csrFile.getAbsolutePath())); |
| | | if(keyStore == null) { |
| | | Message msg = ERR_CERTMGR_KEYSTORE_NONEXISTANT.get(); |
| | | throw new KeyStoreException(msg.toString()); |
| | | } |
| | | PrivateKey privateKey = getPrivateKey(keyStore, alias, pwd); |
| | | if(privateKey == null) { |
| | | Message msg = ERR_CERTMGR_PRIVATE_KEY.get(alias); |
| | | throw new KeyStoreException(msg.toString()); |
| | | } |
| | | Certificate cert = keyStore.getCertificate(alias); |
| | | if(cert == null) { |
| | | Message msg = ERR_CERTMGR_ALIAS_NO_CERTIFICATE.get(alias); |
| | | throw new KeyStoreException(msg.toString()); |
| | | } |
| | | Signature signature = Signature.getInstance(SIG_ALGORITHM); |
| | | signature.initSign(privateKey); |
| | | Object request = pkcs10Cons.newInstance(cert.getPublicKey()); |
| | | Object subject = X500NameCons.newInstance(dn); |
| | | Method encodeAndSign = |
| | | PKCS10Class.getMethod(ENCODE_SIGN_METHOD, X500NameClass, |
| | | Signature.class); |
| | | Method print = |
| | | PKCS10Class.getMethod(PRINT_METHOD, PrintStream.class); |
| | | encodeAndSign.invoke(request, subject, signature); |
| | | print.invoke(request, printStream); |
| | | printStream.close(); |
| | | } catch (Exception e) { |
| | | e.printStackTrace(); |
| | | Message msg = ERR_CERTMGR_CERT_REQUEST.get(alias,e.getMessage()); |
| | | throw new KeyStoreException(msg.toString()); |
| | | } |
| | | return csrFile; |
| | | } |
| | | } |
| | | |
| | | /** |
| | | * Default JDK 6 platform class. |
| | | */ |
| | | private static class JDK6PlatformIMPL extends PlatformIMPL { |
| | | //normalize method. |
| | | private static final Method NORMALIZE; |
| | | //Normalized form method. |
| | | private static final Object FORM_NFKC; |
| | | |
| | | private static Class<?> X500SignerClass; |
| | | private static Constructor<?> X500SignerCons; |
| | | |
| | | static { |
| | | Method normalize = null; |
| | | Object formNFKC = null; |
| | | String x509pkg = pkgPrefix + ".x509"; |
| | | String X500Signer = x509pkg + ".X500Signer"; |
| | | try { |
| | | Class<?> normalizer = Class.forName("java.text.Normalizer"); |
| | | Class<?> normalizerForm = Class.forName("java.text.Normalizer$Form"); |
| | | normalize = normalizer.getMethod("normalize", CharSequence.class, |
| | | normalizerForm); |
| | | formNFKC = normalizerForm.getField("NFKD").get(null); |
| | | X500SignerClass = Class.forName(X500Signer); |
| | | X500SignerCons = X500SignerClass.getConstructor(Signature.class, |
| | | X500NameClass); |
| | | } |
| | | catch (ClassNotFoundException e) { |
| | | Message msg = ERR_CERTMGR_CLASS_NOT_FOUND.get(e.getMessage()); |
| | | throw new ExceptionInInitializerError(msg.toString()); |
| | | } catch (SecurityException e) { |
| | | Message msg = ERR_CERTMGR_SECURITY.get(e.getMessage()); |
| | | throw new ExceptionInInitializerError(msg.toString()); |
| | | } catch (NoSuchMethodException e) { |
| | | Message msg = ERR_CERTMGR_NO_METHOD.get(e.getMessage()); |
| | | throw new ExceptionInInitializerError(msg.toString()); |
| | | } |
| | | catch (Exception ex) { |
| | | // Do not use Normalizer. The values are already set to null. |
| | | } |
| | | NORMALIZE = normalize; |
| | | FORM_NFKC = formNFKC; |
| | | } |
| | | |
| | | |
| | | @Override |
| | | public void normalize(StringBuilder buffer) { |
| | | |
| | | try { |
| | | String normal = (String) NORMALIZE.invoke(null, buffer, FORM_NFKC); |
| | | buffer.replace(0,buffer.length(),normal); |
| | | } |
| | | catch(Exception ex) { |
| | | //Don't do anything. buffer should be used. |
| | | } |
| | | } |
| | | |
| | | /** |
| | | * Generate a certificate request. Note that this methods checks if |
| | | * the certificate request generation is allowed and throws an |
| | | * exception if it isn't supported. Some vendors JDKs aren't compatible |
| | | * with Sun's certificate request generation classes so they aren't |
| | | * supported. Note this method uses the X500Signer class which has been |
| | | * deprecated in JDK 1.7. |
| | | * |
| | | * @param ks The keystore to use in the request creation. |
| | | * @param ksType The keystore type. |
| | | * @param ksPath The path to the keystore. |
| | | * @param alias The alias to use in the request generation. |
| | | * @param pwd The keystore password to use. |
| | | * @param dn A dn string to use as the certificate subject. |
| | | * |
| | | * @return A file object pointing at the created certificate request. |
| | | * @throws KeyStoreException If the certificate request failed. |
| | | */ |
| | | public File |
| | | generateCertificateRequest(KeyStore ks, String ksType, String ksPath, |
| | | String alias, char[] pwd, String dn) throws KeyStoreException { |
| | | if(!certReqAllowed) { |
| | | String vendor = System.getProperty("java.vendor"); |
| | | Message msg = |
| | | ERR_CERTMGR_CERT_SIGN_REQ_NOT_SUPPORTED.get(vendor); |
| | | throw new KeyStoreException(msg.toString()); |
| | | } |
| | | KeyStore keyStore = generateSelfSignedCertificate(ks, ksType, ksPath, |
| | | alias, pwd, dn, DEFAULT_VALIDITY); |
| | | File csrFile; |
| | | try { |
| | | csrFile = File.createTempFile(TMPFILE_PREFIX, TMPFILE_EXT); |
| | | csrFile.deleteOnExit(); |
| | | PrintStream printStream = |
| | | new PrintStream(new FileOutputStream(csrFile.getAbsolutePath())); |
| | | if(keyStore == null) { |
| | | Message msg = ERR_CERTMGR_KEYSTORE_NONEXISTANT.get(); |
| | | throw new KeyStoreException(msg.toString()); |
| | | } |
| | | PrivateKey privateKey = getPrivateKey(keyStore, alias, pwd); |
| | | if(privateKey == null) { |
| | | Message msg = ERR_CERTMGR_PRIVATE_KEY.get(alias); |
| | | throw new KeyStoreException(msg.toString()); |
| | | } |
| | | Certificate cert = keyStore.getCertificate(alias); |
| | | if(cert == null) { |
| | | Message msg = ERR_CERTMGR_ALIAS_NO_CERTIFICATE.get(alias); |
| | | throw new KeyStoreException(msg.toString()); |
| | | } |
| | | Signature signature = Signature.getInstance(SIG_ALGORITHM); |
| | | signature.initSign(privateKey); |
| | | Object request = pkcs10Cons.newInstance(cert.getPublicKey()); |
| | | Object subject = X500NameCons.newInstance(dn); |
| | | Object signer = |
| | | X500SignerCons.newInstance(signature, subject); |
| | | Method encodeAndSign = |
| | | PKCS10Class.getMethod(ENCODE_SIGN_METHOD, X500SignerClass); |
| | | Method print = |
| | | PKCS10Class.getMethod(PRINT_METHOD, PrintStream.class); |
| | | encodeAndSign.invoke(request, signer); |
| | | print.invoke(request, printStream); |
| | | printStream.close(); |
| | | } catch (Exception e) { |
| | | Message msg = ERR_CERTMGR_CERT_REQUEST.get(alias,e.getMessage()); |
| | | throw new KeyStoreException(msg.toString()); |
| | | } |
| | | return csrFile; |
| | | } |
| | | } |
| | | |
| | | |
| | | |
| | | |
| | | /** |
| | | * IBM JDK 5 platform class. |
| | | */ |
| | | private static class IBM5PlatformIMPL extends PlatformIMPL { |
| | | |
| | | //Classes needed to manage certificates. |
| | | private static Class<?> X500SignerClass; |
| | | private static Constructor<?> X500SignerCons; |
| | | |
| | | static { |
| | | String x509pkg = pkgPrefix + ".x509"; |
| | | String X500Signer = x509pkg + ".X500Signer"; |
| | | try { |
| | | X500SignerClass = Class.forName(X500Signer); |
| | | X500SignerCons = X500SignerClass.getConstructor(Signature.class, |
| | | X500NameClass); |
| | | } |
| | | catch (ClassNotFoundException e) { |
| | | Message msg = ERR_CERTMGR_CLASS_NOT_FOUND.get(e.getMessage()); |
| | | throw new ExceptionInInitializerError(msg.toString()); |
| | | } catch (SecurityException e) { |
| | | Message msg = ERR_CERTMGR_SECURITY.get(e.getMessage()); |
| | | throw new ExceptionInInitializerError(msg.toString()); |
| | | } catch (NoSuchMethodException e) { |
| | | Message msg = ERR_CERTMGR_NO_METHOD.get(e.getMessage()); |
| | | throw new ExceptionInInitializerError(msg.toString()); |
| | | } |
| | | } |
| | | |
| | | @Override |
| | | public void normalize(StringBuilder buffer) { |
| | | //No implementation. |
| | | } |
| | | |
| | | /** |
| | | * Generate a certificate request. Note that this methods checks if |
| | | * the certificate request generation is allowed and throws an |
| | | * exception if it isn't supported. Some vendors JDKs aren't compatible |
| | | * with Sun's certificate request generation classes so they aren't |
| | | * supported. Note this method uses the X500Signer class which has been |
| | | * deprecated in JDK 1.7. |
| | | * |
| | | * @param ks The keystore to use in the request creation. |
| | | * @param ksType The keystore type. |
| | | * @param ksPath The path to the keystore. |
| | | * @param alias The alias to use in the request generation. |
| | | * @param pwd The keystore password to use. |
| | | * @param dn A dn string to use as the certificate subject. |
| | | * |
| | | * @return A file object pointing at the created certificate request. |
| | | * @throws KeyStoreException If the certificate request failed. |
| | | */ |
| | | public File |
| | | generateCertificateRequest(KeyStore ks, String ksType, String ksPath, |
| | | String alias, char[] pwd, String dn) throws KeyStoreException { |
| | | if(!certReqAllowed) { |
| | | String vendor = System.getProperty("java.vendor"); |
| | | Message msg = |
| | | ERR_CERTMGR_CERT_SIGN_REQ_NOT_SUPPORTED.get(vendor); |
| | | throw new KeyStoreException(msg.toString()); |
| | | } |
| | | KeyStore keyStore = generateSelfSignedCertificate(ks, ksType, ksPath, |
| | | alias, pwd, dn, DEFAULT_VALIDITY); |
| | | File csrFile; |
| | | try { |
| | | csrFile = File.createTempFile(TMPFILE_PREFIX, TMPFILE_EXT); |
| | | csrFile.deleteOnExit(); |
| | | PrintStream printStream = |
| | | new PrintStream(new FileOutputStream(csrFile.getAbsolutePath())); |
| | | if(keyStore == null) { |
| | | Message msg = ERR_CERTMGR_KEYSTORE_NONEXISTANT.get(); |
| | | throw new KeyStoreException(msg.toString()); |
| | | } |
| | | PrivateKey privateKey = getPrivateKey(keyStore, alias, pwd); |
| | | if(privateKey == null) { |
| | | Message msg = ERR_CERTMGR_PRIVATE_KEY.get(alias); |
| | | throw new KeyStoreException(msg.toString()); |
| | | } |
| | | Certificate cert = keyStore.getCertificate(alias); |
| | | if(cert == null) { |
| | | Message msg = ERR_CERTMGR_ALIAS_NO_CERTIFICATE.get(alias); |
| | | throw new KeyStoreException(msg.toString()); |
| | | } |
| | | Signature signature = Signature.getInstance(SIG_ALGORITHM); |
| | | signature.initSign(privateKey); |
| | | Object request = pkcs10Cons.newInstance(cert.getPublicKey()); |
| | | Object subject = X500NameCons.newInstance(dn); |
| | | Object signer = |
| | | X500SignerCons.newInstance(signature, subject); |
| | | Method encodeAndSign = |
| | | PKCS10Class.getMethod(ENCODE_SIGN_METHOD, X500SignerClass); |
| | | Method print = |
| | | PKCS10Class.getMethod(PRINT_METHOD, PrintStream.class); |
| | | encodeAndSign.invoke(request, signer); |
| | | print.invoke(request, printStream); |
| | | printStream.close(); |
| | | } catch (Exception e) { |
| | | Message msg = ERR_CERTMGR_CERT_REQUEST.get(alias,e.getMessage()); |
| | | throw new KeyStoreException(msg.toString()); |
| | | } |
| | | return csrFile; |
| | | } |
| | | } |
| | | |
| | | |
| | | |
| | | /** |
| | | * Normalize the specified buffer. |