| | |
| | | package org.opends.server.util; |
| | | |
| | | |
| | | |
| | | import java.security.KeyStoreException; |
| | | import java.security.KeyStore; |
| | | import java.security.PrivateKey; |
| | |
| | | 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. |
| | | * |
| | | * Provides a wrapper class that collects all of the JVM vendor and JDK version |
| | | * specific code in a single place. |
| | | */ |
| | | public final class Platform { |
| | | public final class Platform |
| | | { |
| | | |
| | | //Prefix that determines which security package to use. |
| | | private static String pkgPrefix; |
| | | // Prefix that determines which security package to use. |
| | | private static String pkgPrefix; |
| | | |
| | | //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"; |
| | | // 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"; |
| | | |
| | | private static final PlatformIMPL IMPL; |
| | | private static final PlatformIMPL IMPL; |
| | | |
| | | static { |
| | | String vendor = System.getProperty("java.vendor"); |
| | | String ver = System.getProperty("java.version"); |
| | | static |
| | | { |
| | | String vendor = System.getProperty("java.vendor"); |
| | | String ver = System.getProperty("java.version"); |
| | | |
| | | if(vendor.startsWith("IBM")) |
| | | if (vendor.startsWith("IBM")) |
| | | { |
| | | pkgPrefix = IBM_SEC; |
| | | if (ver.startsWith("1.5")) |
| | | { |
| | | pkgPrefix = IBM_SEC; |
| | | if(ver.startsWith("1.5")) |
| | | { |
| | | IMPL = new IBM5PlatformIMPL(); |
| | | } |
| | | else |
| | | { |
| | | IMPL = new DefaultPlatformIMPL(); |
| | | } |
| | | IMPL = new IBM5PlatformIMPL(); |
| | | } |
| | | else |
| | | { |
| | | pkgPrefix = SUN_SEC; |
| | | if(ver.startsWith("1.5")) |
| | | IMPL = new DefaultPlatformIMPL(); |
| | | } |
| | | } |
| | | else |
| | | { |
| | | pkgPrefix = SUN_SEC; |
| | | if (ver.startsWith("1.5")) |
| | | { |
| | | IMPL = new Sun5PlatformIMPL(); |
| | | } |
| | | else |
| | | { |
| | | IMPL = new DefaultPlatformIMPL(); |
| | | } |
| | | } |
| | | } |
| | | |
| | | |
| | | |
| | | /** |
| | | * Platform base class. Performs all of the certificate management functions. |
| | | */ |
| | | private abstract static class PlatformIMPL |
| | | { |
| | | |
| | | // Key size, key algorithm and signature algorithms used. |
| | | private static final int KEY_SIZE = 1024; |
| | | private static final String KEY_ALGORITHM = "rsa"; |
| | | private static final String SIG_ALGORITHM = "SHA1WithRSA"; |
| | | |
| | | // Time values used in validity calculations. |
| | | private static final int SEC_IN_DAY = 24 * 60 * 60; |
| | | |
| | | // Methods pulled from the classes. |
| | | 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"; |
| | | |
| | | // Classes needed to manage certificates. |
| | | private static Class<?> certKeyGenClass, X500NameClass; |
| | | |
| | | // Constructors for each of the above classes. |
| | | private static Constructor<?> certKeyGenCons, X500NameCons; |
| | | |
| | | static |
| | | { |
| | | String x509pkg = pkgPrefix + ".x509"; |
| | | String certAndKeyGen = x509pkg + ".CertAndKeyGen"; |
| | | String X500Name = x509pkg + ".X500Name"; |
| | | try |
| | | { |
| | | certKeyGenClass = Class.forName(certAndKeyGen); |
| | | X500NameClass = Class.forName(X500Name); |
| | | certKeyGenCons = certKeyGenClass.getConstructor(String.class, |
| | | String.class); |
| | | X500NameCons = X500NameClass.getConstructor(String.class); |
| | | } |
| | | 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()); |
| | | } |
| | | } |
| | | |
| | | |
| | | |
| | | protected PlatformIMPL() |
| | | { |
| | | } |
| | | |
| | | |
| | | |
| | | /** |
| | | * Delete the specified alias from the specified keystore. |
| | | * |
| | | * @param ks |
| | | * The keystore to delete the alias from. |
| | | * @param ksPath |
| | | * The path to the keystore. |
| | | * @param alias |
| | | * The alias to use in the request generation. |
| | | * @param pwd |
| | | * The keystore password to use. |
| | | * @throws KeyStoreException |
| | | * If an error occurred deleting the alias. |
| | | */ |
| | | public final void deleteAlias(KeyStore ks, String ksPath, String alias, |
| | | char[] pwd) throws KeyStoreException |
| | | { |
| | | try |
| | | { |
| | | if (ks == null) |
| | | { |
| | | IMPL = new Sun5PlatformIMPL(); |
| | | Message msg = ERR_CERTMGR_KEYSTORE_NONEXISTANT.get(); |
| | | throw new KeyStoreException(msg.toString()); |
| | | } |
| | | ks.deleteEntry(alias); |
| | | FileOutputStream fs = new FileOutputStream(ksPath); |
| | | ks.store(fs, pwd); |
| | | fs.close(); |
| | | } |
| | | catch (Exception e) |
| | | { |
| | | Message msg = ERR_CERTMGR_DELETE_ALIAS.get(alias, e.getMessage()); |
| | | throw new KeyStoreException(msg.toString()); |
| | | } |
| | | } |
| | | |
| | | |
| | | |
| | | /** |
| | | * Add the certificate in the specified path to the specified keystore, |
| | | * creating the keystore using the specified type and path if it the |
| | | * keystore doesn't exist. |
| | | * |
| | | * @param ks |
| | | * The keystore to add the certificate to, may be null if it |
| | | * doesn't exist. |
| | | * @param ksType |
| | | * The type to use if the keystore is created. |
| | | * @param ksPath |
| | | * The path to the keystore if it is created. |
| | | * @param alias |
| | | * The alias to store the certificate under. |
| | | * @param pwd |
| | | * The password to use in saving the certificate. |
| | | * @param certPath |
| | | * The path to the file containing the certificate. |
| | | * @throws KeyStoreException |
| | | * If an error occurred adding the certificate to the keystore. |
| | | */ |
| | | public final void addCertificate(KeyStore ks, String ksType, String ksPath, |
| | | String alias, char[] pwd, String certPath) throws KeyStoreException |
| | | { |
| | | try |
| | | { |
| | | CertificateFactory cf = CertificateFactory.getInstance("X509"); |
| | | InputStream inStream = new FileInputStream(certPath); |
| | | if (ks == null) |
| | | { |
| | | ks = KeyStore.getInstance(ksType); |
| | | ks.load(null, pwd); |
| | | } |
| | | // Do not support certificate replies. |
| | | if (ks.entryInstanceOf(alias, KeyStore.PrivateKeyEntry.class)) |
| | | { |
| | | Message msg = ERR_CERTMGR_CERT_REPLIES_INVALID.get(alias); |
| | | throw new KeyStoreException(msg.toString()); |
| | | } |
| | | else if (!ks.containsAlias(alias) |
| | | || ks |
| | | .entryInstanceOf(alias, KeyStore.TrustedCertificateEntry.class)) |
| | | trustedCert(alias, cf, ks, inStream); |
| | | else |
| | | { |
| | | IMPL = new DefaultPlatformIMPL(); |
| | | Message msg = ERR_CERTMGR_ALIAS_INVALID.get(alias); |
| | | throw new KeyStoreException(msg.toString()); |
| | | } |
| | | FileOutputStream fileOutStream = new FileOutputStream(ksPath); |
| | | ks.store(fileOutStream, pwd); |
| | | fileOutStream.close(); |
| | | inStream.close(); |
| | | } |
| | | catch (Exception e) |
| | | { |
| | | Message msg = ERR_CERTMGR_ADD_CERT.get(alias, e.getMessage()); |
| | | throw new KeyStoreException(msg.toString()); |
| | | } |
| | | } |
| | | |
| | | /** |
| | | * Platform base class. Performs all of the certificate management functions. |
| | | */ |
| | | private abstract static class PlatformIMPL { |
| | | |
| | | //Key size, key algorithm and signature algorithms used. |
| | | private static final int KEY_SIZE = 1024; |
| | | private static final String KEY_ALGORITHM = "rsa"; |
| | | private static final String SIG_ALGORITHM = "SHA1WithRSA"; |
| | | |
| | | //Time values used in validity calculations. |
| | | private static final int SEC_IN_DAY = 24 * 60 * 60; |
| | | |
| | | //Methods pulled from the classes. |
| | | 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"; |
| | | |
| | | //Classes needed to manage certificates. |
| | | private static Class<?> certKeyGenClass, X500NameClass; |
| | | |
| | | //Constructors for each of the above classes. |
| | | private static Constructor<?> certKeyGenCons, X500NameCons; |
| | | |
| | | static { |
| | | String x509pkg = pkgPrefix + ".x509"; |
| | | String certAndKeyGen= x509pkg + ".CertAndKeyGen"; |
| | | String X500Name = x509pkg + ".X500Name"; |
| | | try { |
| | | certKeyGenClass = Class.forName(certAndKeyGen); |
| | | X500NameClass = Class.forName(X500Name); |
| | | certKeyGenCons = |
| | | certKeyGenClass.getConstructor(String.class, String.class); |
| | | X500NameCons = X500NameClass.getConstructor(String.class); |
| | | } 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()); |
| | | } |
| | | } |
| | | |
| | | |
| | | protected PlatformIMPL() {} |
| | | |
| | | |
| | | /** |
| | | * Delete the specified alias from the specified keystore. |
| | | * |
| | | * @param ks The keystore to delete the alias from. |
| | | * @param ksPath The path to the keystore. |
| | | * @param alias The alias to use in the request generation. |
| | | * @param pwd The keystore password to use. |
| | | * |
| | | * @throws KeyStoreException If an error occurred deleting the alias. |
| | | */ |
| | | public final void deleteAlias(KeyStore ks, String ksPath, |
| | | String alias, char[] pwd) throws KeyStoreException { |
| | | try { |
| | | if(ks == null) { |
| | | Message msg = ERR_CERTMGR_KEYSTORE_NONEXISTANT.get(); |
| | | throw new KeyStoreException(msg.toString()); |
| | | } |
| | | ks.deleteEntry(alias); |
| | | FileOutputStream fs = new FileOutputStream(ksPath); |
| | | ks.store(fs, pwd); |
| | | fs.close(); |
| | | } catch (Exception e) { |
| | | Message msg = |
| | | ERR_CERTMGR_DELETE_ALIAS.get(alias,e.getMessage()); |
| | | throw new KeyStoreException(msg.toString()); |
| | | } |
| | | } |
| | | |
| | | |
| | | /** |
| | | * Add the certificate in the specified path to the specified keystore, |
| | | * creating the keystore using the specified type and path if it the |
| | | * keystore doesn't exist. |
| | | * |
| | | * @param ks The keystore to add the certificate to, may be null if it |
| | | * doesn't exist. |
| | | * @param ksType The type to use if the keystore is created. |
| | | * @param ksPath The path to the keystore if it is created. |
| | | * @param alias The alias to store the certificate under. |
| | | * @param pwd The password to use in saving the certificate. |
| | | * @param certPath The path to the file containing the certificate. |
| | | * @throws KeyStoreException If an error occurred adding the |
| | | * certificate to the keystore. |
| | | */ |
| | | public final void addCertificate(KeyStore ks, String ksType, |
| | | String ksPath, String alias, char[] pwd, String certPath) |
| | | throws KeyStoreException { |
| | | try { |
| | | CertificateFactory cf = CertificateFactory.getInstance("X509"); |
| | | InputStream inStream = new FileInputStream(certPath); |
| | | if(ks == null) { |
| | | ks = KeyStore.getInstance(ksType); |
| | | ks.load(null, pwd); |
| | | } |
| | | //Do not support certificate replies. |
| | | if (ks.entryInstanceOf(alias ,KeyStore.PrivateKeyEntry.class)) { |
| | | Message msg = ERR_CERTMGR_CERT_REPLIES_INVALID.get(alias); |
| | | throw new KeyStoreException(msg.toString()); |
| | | } else if(!ks.containsAlias(alias) || |
| | | ks.entryInstanceOf(alias, |
| | | KeyStore.TrustedCertificateEntry.class)) |
| | | trustedCert(alias, cf, ks, inStream); |
| | | else { |
| | | Message msg = ERR_CERTMGR_ALIAS_INVALID.get(alias); |
| | | throw new KeyStoreException(msg.toString()); |
| | | } |
| | | FileOutputStream fileOutStream = new FileOutputStream(ksPath); |
| | | ks.store(fileOutStream, pwd); |
| | | fileOutStream.close(); |
| | | inStream.close(); |
| | | } catch (Exception e) { |
| | | Message msg = |
| | | ERR_CERTMGR_ADD_CERT.get(alias, e.getMessage()); |
| | | throw new KeyStoreException(msg.toString()); |
| | | } |
| | | } |
| | | |
| | | |
| | | /** |
| | | * Generate a self-signed certificate using the specified alias, dn |
| | | * string and validity period. If the keystore does not exist, create it |
| | | * using the specified type and path. |
| | | * |
| | | * @param ks The keystore to save the certificate in. May be null if it |
| | | * does not exist. |
| | | * @param ksType The keystore type to use if the keystore is created. |
| | | * @param ksPath The path to the keystore if the keystore is created. |
| | | * @param alias The alias to store the certificate under. |
| | | * @param pwd The password to us in saving the certificate. |
| | | * @param dn The dn string used as the certificate subject. |
| | | * @param validity The validity of the certificate in days. |
| | | * @return The keystore that the self-signed certificate was stored in. |
| | | * |
| | | * @throws KeyStoreException If the self-signed certificate cannot be |
| | | * generated. |
| | | */ |
| | | public final |
| | | KeyStore generateSelfSignedCertificate(KeyStore ks, String ksType, |
| | | String ksPath, String alias, char[] pwd, String dn, int validity) |
| | | throws KeyStoreException { |
| | | try { |
| | | if(ks == null) { |
| | | ks = KeyStore.getInstance(ksType); |
| | | ks.load(null, pwd); |
| | | } else if(ks.containsAlias(alias)) { |
| | | Message msg = ERR_CERTMGR_ALIAS_ALREADY_EXISTS.get(alias); |
| | | throw new KeyStoreException(msg.toString()); |
| | | } |
| | | Object keypair = |
| | | certKeyGenCons.newInstance(KEY_ALGORITHM, SIG_ALGORITHM); |
| | | Object subject = X500NameCons.newInstance(dn); |
| | | Method certAndKeyGenGenerate = |
| | | certKeyGenClass.getMethod(GENERATE_METHOD, int.class); |
| | | certAndKeyGenGenerate.invoke(keypair, KEY_SIZE); |
| | | Method certAndKeyGetPrivateKey = |
| | | certKeyGenClass.getMethod(GET_PRIVATE_KEY_METHOD); |
| | | PrivateKey privatevKey = |
| | | (PrivateKey) certAndKeyGetPrivateKey.invoke(keypair); |
| | | Certificate[] certificateChain = new Certificate[1]; |
| | | Method getSelfCertificate = |
| | | certKeyGenClass.getMethod(GET_SELFSIGNED_CERT_METHOD, |
| | | X500NameClass,long.class); |
| | | int days = validity * SEC_IN_DAY; |
| | | certificateChain[0] = |
| | | (Certificate) getSelfCertificate.invoke(keypair, subject, days); |
| | | ks.setKeyEntry(alias, privatevKey, pwd, certificateChain); |
| | | FileOutputStream fileOutStream = new FileOutputStream(ksPath); |
| | | ks.store(fileOutStream, pwd); |
| | | fileOutStream.close(); |
| | | } catch (Exception e) { |
| | | Message msg = |
| | | ERR_CERTMGR_GEN_SELF_SIGNED_CERT.get(alias, e.getMessage()); |
| | | throw new KeyStoreException(msg.toString()); |
| | | } |
| | | return ks; |
| | | } |
| | | |
| | | |
| | | /** |
| | | * Generate a x509 certificate from the input stream. Verification is |
| | | * done only if it is self-signed. |
| | | * |
| | | * @param alias The alias to save the certificate under. |
| | | * @param cf The x509 certificate factory. |
| | | * @param ks The keystore to add the certificate in. |
| | | * @param in The input stream to read the certificate from. |
| | | * @throws KeyStoreException If the alias exists already in the |
| | | * keystore, if the self-signed certificate didn't verify, or |
| | | * the certificate could not be stored. |
| | | */ |
| | | private void trustedCert(String alias, CertificateFactory cf, |
| | | KeyStore ks, InputStream in) throws KeyStoreException { |
| | | try { |
| | | if (ks.containsAlias(alias)) { |
| | | Message msg = ERR_CERTMGR_ALIAS_ALREADY_EXISTS.get(alias); |
| | | throw new KeyStoreException(msg.toString()); |
| | | } |
| | | X509Certificate cert = (X509Certificate) cf.generateCertificate(in); |
| | | if (isSelfSigned(cert)) |
| | | cert.verify(cert.getPublicKey()); |
| | | ks.setCertificateEntry(alias, cert); |
| | | } catch (Exception e) { |
| | | Message msg = |
| | | ERR_CERTMGR_TRUSTED_CERT.get(alias,e.getMessage()); |
| | | throw new KeyStoreException(msg.toString()); |
| | | } |
| | | } |
| | | |
| | | |
| | | /** |
| | | * Check that the issuer and subject DNs match. |
| | | * |
| | | * @param cert The certificate to examine. |
| | | * @return {@code true} if the certificate is self-signed. |
| | | */ |
| | | private boolean isSelfSigned(X509Certificate cert) { |
| | | return cert.getSubjectDN().equals(cert.getIssuerDN()); |
| | | } |
| | | |
| | | /** |
| | | * Normalize the data in the specified buffer. |
| | | * |
| | | * @param buffer The buffer to normalize. |
| | | */ |
| | | public abstract void normalize(StringBuilder buffer); |
| | | } |
| | | |
| | | //Prevent instantiation. |
| | | private Platform() {} |
| | | |
| | | /** |
| | | * Add the certificate in the specified path to the provided keystore; |
| | | * creating the keystore with the provided type and path if it doesn't |
| | | * exist. |
| | | * |
| | | * @param ks The keystore to add the certificate to, may be null if it |
| | | * doesn't exist. |
| | | * @param ksType The type to use if the keystore is created. |
| | | * @param ksPath The path to the keystore if it is created. |
| | | * @param alias The alias to store the certificate under. |
| | | * @param pwd The password to use in saving the certificate. |
| | | * @param certPath The path to the file containing the certificate. |
| | | * |
| | | * @throws KeyStoreException If an error occurred adding the |
| | | * certificate to the keystore. |
| | | */ |
| | | public static void addCertificate(KeyStore ks, String ksType, String ksPath, |
| | | String alias, char[] pwd, String certPath) throws KeyStoreException { |
| | | IMPL.addCertificate(ks,ksType, ksPath, alias, pwd, certPath); |
| | | } |
| | | |
| | | |
| | | /** |
| | | * Delete the specified alias from the provided keystore. |
| | | * Generate a self-signed certificate using the specified alias, dn string |
| | | * and validity period. If the keystore does not exist, create it using the |
| | | * specified type and path. |
| | | * |
| | | * @param ks The keystore to delete the alias from. |
| | | * @param ksPath The path to the keystore. |
| | | * @param alias The alias to use in the request generation. |
| | | * @param pwd The keystore password to use. |
| | | * |
| | | * @throws KeyStoreException If an error occurred deleting the alias. |
| | | * @param ks |
| | | * The keystore to save the certificate in. May be null if it does |
| | | * not exist. |
| | | * @param ksType |
| | | * The keystore type to use if the keystore is created. |
| | | * @param ksPath |
| | | * The path to the keystore if the keystore is created. |
| | | * @param alias |
| | | * The alias to store the certificate under. |
| | | * @param pwd |
| | | * The password to us in saving the certificate. |
| | | * @param dn |
| | | * The dn string used as the certificate subject. |
| | | * @param validity |
| | | * The validity of the certificate in days. |
| | | * @return The keystore that the self-signed certificate was stored in. |
| | | * @throws KeyStoreException |
| | | * If the self-signed certificate cannot be generated. |
| | | */ |
| | | public static void deleteAlias(KeyStore ks, String ksPath, String alias, |
| | | char[] pwd) throws KeyStoreException { |
| | | IMPL.deleteAlias(ks, ksPath, alias, pwd); |
| | | } |
| | | |
| | | |
| | | /** |
| | | * 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. |
| | | * |
| | | * @param ks The keystore to save the certificate in. May be null if it |
| | | * does not exist. |
| | | * @param ksType The keystore type to use if the keystore is created. |
| | | * @param ksPath The path to the keystore if the keystore is created. |
| | | * @param alias The alias to store the certificate under. |
| | | * @param pwd The password to us in saving the certificate. |
| | | * @param dn The dn string used as the certificate subject. |
| | | * @param validity The validity of the certificate in days. |
| | | * |
| | | * @throws KeyStoreException If the self-signed certificate cannot be |
| | | * generated. |
| | | */ |
| | | public static void generateSelfSignedCertificate(KeyStore ks, String ksType, |
| | | String ksPath, String alias, char[] pwd, String dn, int validity) |
| | | throws KeyStoreException { |
| | | IMPL.generateSelfSignedCertificate(ks, ksType, ksPath, alias, pwd, dn, |
| | | validity); |
| | | public final KeyStore generateSelfSignedCertificate(KeyStore ks, |
| | | String ksType, String ksPath, String alias, char[] pwd, String dn, |
| | | int validity) throws KeyStoreException |
| | | { |
| | | try |
| | | { |
| | | if (ks == null) |
| | | { |
| | | ks = KeyStore.getInstance(ksType); |
| | | ks.load(null, pwd); |
| | | } |
| | | else if (ks.containsAlias(alias)) |
| | | { |
| | | Message msg = ERR_CERTMGR_ALIAS_ALREADY_EXISTS.get(alias); |
| | | throw new KeyStoreException(msg.toString()); |
| | | } |
| | | Object keypair = certKeyGenCons.newInstance(KEY_ALGORITHM, |
| | | SIG_ALGORITHM); |
| | | Object subject = X500NameCons.newInstance(dn); |
| | | Method certAndKeyGenGenerate = certKeyGenClass.getMethod( |
| | | GENERATE_METHOD, int.class); |
| | | certAndKeyGenGenerate.invoke(keypair, KEY_SIZE); |
| | | Method certAndKeyGetPrivateKey = certKeyGenClass |
| | | .getMethod(GET_PRIVATE_KEY_METHOD); |
| | | PrivateKey privatevKey = (PrivateKey) certAndKeyGetPrivateKey |
| | | .invoke(keypair); |
| | | Certificate[] certificateChain = new Certificate[1]; |
| | | Method getSelfCertificate = certKeyGenClass.getMethod( |
| | | GET_SELFSIGNED_CERT_METHOD, X500NameClass, long.class); |
| | | int days = validity * SEC_IN_DAY; |
| | | certificateChain[0] = (Certificate) getSelfCertificate.invoke(keypair, |
| | | subject, days); |
| | | ks.setKeyEntry(alias, privatevKey, pwd, certificateChain); |
| | | FileOutputStream fileOutStream = new FileOutputStream(ksPath); |
| | | ks.store(fileOutStream, pwd); |
| | | fileOutStream.close(); |
| | | } |
| | | catch (Exception e) |
| | | { |
| | | Message msg = ERR_CERTMGR_GEN_SELF_SIGNED_CERT.get(alias, e |
| | | .getMessage()); |
| | | throw new KeyStoreException(msg.toString()); |
| | | } |
| | | return ks; |
| | | } |
| | | |
| | | |
| | | |
| | | /** |
| | | * Sun 5 JDK platform class. |
| | | * Generate a x509 certificate from the input stream. Verification is done |
| | | * only if it is self-signed. |
| | | * |
| | | * @param alias |
| | | * The alias to save the certificate under. |
| | | * @param cf |
| | | * The x509 certificate factory. |
| | | * @param ks |
| | | * The keystore to add the certificate in. |
| | | * @param in |
| | | * The input stream to read the certificate from. |
| | | * @throws KeyStoreException |
| | | * If the alias exists already in the keystore, if the self-signed |
| | | * certificate didn't verify, or the certificate could not be |
| | | * stored. |
| | | */ |
| | | private static class Sun5PlatformIMPL extends PlatformIMPL { |
| | | //normalize method. |
| | | private static final Method NORMALIZE; |
| | | //Normalized form method. |
| | | private static final Object FORM_NFKC; |
| | | |
| | | static { |
| | | Method normalize = null; |
| | | Object formNFKC = null; |
| | | 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); |
| | | private void trustedCert(String alias, CertificateFactory cf, KeyStore ks, |
| | | InputStream in) throws KeyStoreException |
| | | { |
| | | try |
| | | { |
| | | if (ks.containsAlias(alias)) |
| | | { |
| | | Message msg = ERR_CERTMGR_ALIAS_ALREADY_EXISTS.get(alias); |
| | | throw new KeyStoreException(msg.toString()); |
| | | } |
| | | catch (Exception ex) { |
| | | X509Certificate cert = (X509Certificate) cf.generateCertificate(in); |
| | | if (isSelfSigned(cert)) cert.verify(cert.getPublicKey()); |
| | | ks.setCertificateEntry(alias, cert); |
| | | } |
| | | catch (Exception e) |
| | | { |
| | | Message msg = ERR_CERTMGR_TRUSTED_CERT.get(alias, e.getMessage()); |
| | | throw new KeyStoreException(msg.toString()); |
| | | } |
| | | } |
| | | |
| | | |
| | | |
| | | /** |
| | | * Check that the issuer and subject DNs match. |
| | | * |
| | | * @param cert |
| | | * The certificate to examine. |
| | | * @return {@code true} if the certificate is self-signed. |
| | | */ |
| | | private boolean isSelfSigned(X509Certificate cert) |
| | | { |
| | | return cert.getSubjectDN().equals(cert.getIssuerDN()); |
| | | } |
| | | |
| | | |
| | | |
| | | /** |
| | | * Normalize the data in the specified buffer. |
| | | * |
| | | * @param buffer |
| | | * The buffer to normalize. |
| | | */ |
| | | public abstract void normalize(StringBuilder buffer); |
| | | } |
| | | |
| | | |
| | | |
| | | // Prevent instantiation. |
| | | private Platform() |
| | | { |
| | | } |
| | | |
| | | |
| | | |
| | | /** |
| | | * Add the certificate in the specified path to the provided keystore; |
| | | * creating the keystore with the provided type and path if it doesn't exist. |
| | | * |
| | | * @param ks |
| | | * The keystore to add the certificate to, may be null if it doesn't |
| | | * exist. |
| | | * @param ksType |
| | | * The type to use if the keystore is created. |
| | | * @param ksPath |
| | | * The path to the keystore if it is created. |
| | | * @param alias |
| | | * The alias to store the certificate under. |
| | | * @param pwd |
| | | * The password to use in saving the certificate. |
| | | * @param certPath |
| | | * The path to the file containing the certificate. |
| | | * @throws KeyStoreException |
| | | * If an error occurred adding the certificate to the keystore. |
| | | */ |
| | | public static void addCertificate(KeyStore ks, String ksType, String ksPath, |
| | | String alias, char[] pwd, String certPath) throws KeyStoreException |
| | | { |
| | | IMPL.addCertificate(ks, ksType, ksPath, alias, pwd, certPath); |
| | | } |
| | | |
| | | |
| | | |
| | | /** |
| | | * Delete the specified alias from the provided keystore. |
| | | * |
| | | * @param ks |
| | | * The keystore to delete the alias from. |
| | | * @param ksPath |
| | | * The path to the keystore. |
| | | * @param alias |
| | | * The alias to use in the request generation. |
| | | * @param pwd |
| | | * The keystore password to use. |
| | | * @throws KeyStoreException |
| | | * If an error occurred deleting the alias. |
| | | */ |
| | | public static void deleteAlias(KeyStore ks, String ksPath, String alias, |
| | | char[] pwd) throws KeyStoreException |
| | | { |
| | | IMPL.deleteAlias(ks, ksPath, alias, pwd); |
| | | } |
| | | |
| | | |
| | | |
| | | /** |
| | | * 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. |
| | | * |
| | | * @param ks |
| | | * The keystore to save the certificate in. May be null if it does |
| | | * not exist. |
| | | * @param ksType |
| | | * The keystore type to use if the keystore is created. |
| | | * @param ksPath |
| | | * The path to the keystore if the keystore is created. |
| | | * @param alias |
| | | * The alias to store the certificate under. |
| | | * @param pwd |
| | | * The password to us in saving the certificate. |
| | | * @param dn |
| | | * The dn string used as the certificate subject. |
| | | * @param validity |
| | | * The validity of the certificate in days. |
| | | * @throws KeyStoreException |
| | | * If the self-signed certificate cannot be generated. |
| | | */ |
| | | public static void generateSelfSignedCertificate(KeyStore ks, String ksType, |
| | | String ksPath, String alias, char[] pwd, String dn, int validity) |
| | | throws KeyStoreException |
| | | { |
| | | IMPL.generateSelfSignedCertificate(ks, ksType, ksPath, alias, pwd, dn, |
| | | validity); |
| | | } |
| | | |
| | | |
| | | |
| | | /** |
| | | * Sun 5 JDK platform class. |
| | | */ |
| | | private static class Sun5PlatformIMPL extends PlatformIMPL |
| | | { |
| | | // normalize method. |
| | | private static final Method NORMALIZE; |
| | | // Normalized form method. |
| | | private static final Object FORM_NFKC; |
| | | |
| | | static |
| | | { |
| | | Method normalize = null; |
| | | Object formNFKC = null; |
| | | 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); |
| | | } |
| | | 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.toString(), FORM_NFKC,0); |
| | | buffer.replace(0,buffer.length(),normal); |
| | | } |
| | | catch(Exception ex) { |
| | | //Don't do anything. buffer should be used. |
| | | } |
| | | } |
| | | } |
| | | |
| | | /** |
| | | * Default platform class. |
| | | */ |
| | | private static class DefaultPlatformIMPL extends PlatformIMPL { |
| | | //normalize method. |
| | | private static final Method NORMALIZE; |
| | | //Normalized form method. |
| | | private static final Object FORM_NFKC; |
| | | |
| | | static { |
| | | |
| | | Method normalize = null; |
| | | Object formNFKC = null; |
| | | 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); |
| | | } |
| | | 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. |
| | | } |
| | | } |
| | | } |
| | | |
| | | /** |
| | | * IBM JDK 5 platform class. |
| | | */ |
| | | private static class IBM5PlatformIMPL extends PlatformIMPL { |
| | | |
| | | @Override |
| | | public void normalize(StringBuilder buffer) { |
| | | //No implementation. |
| | | public void normalize(StringBuilder buffer) |
| | | { |
| | | try |
| | | { |
| | | String normal = (String) NORMALIZE.invoke(null, buffer.toString(), |
| | | FORM_NFKC, 0); |
| | | buffer.replace(0, buffer.length(), normal); |
| | | } |
| | | catch (Exception ex) |
| | | { |
| | | // Don't do anything. buffer should be used. |
| | | } |
| | | } |
| | | } |
| | | } |
| | | |
| | | /** |
| | | * Normalize the specified buffer. |
| | | * |
| | | * @param buffer The buffer to normalize. |
| | | */ |
| | | public static void normalize(StringBuilder buffer) { |
| | | IMPL.normalize(buffer); |
| | | } |
| | | |
| | | /** |
| | | * Test if a platform java vendor property starts with the specified |
| | | * vendor string. |
| | | * |
| | | * @param vendor The vendor to check for. |
| | | * @return {@code true} if the java vendor starts with the specified vendor |
| | | * string. |
| | | */ |
| | | public static boolean isVendor(String vendor) { |
| | | String javaVendor = System.getProperty("java.vendor"); |
| | | return javaVendor.startsWith(vendor); |
| | | } |
| | | |
| | | /** |
| | | * Default platform class. |
| | | */ |
| | | private static class DefaultPlatformIMPL extends PlatformIMPL |
| | | { |
| | | // normalize method. |
| | | private static final Method NORMALIZE; |
| | | // Normalized form method. |
| | | private static final Object FORM_NFKC; |
| | | |
| | | static |
| | | { |
| | | |
| | | Method normalize = null; |
| | | Object formNFKC = null; |
| | | 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); |
| | | } |
| | | 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. |
| | | } |
| | | } |
| | | } |
| | | |
| | | |
| | | |
| | | /** |
| | | * IBM JDK 5 platform class. |
| | | */ |
| | | private static class IBM5PlatformIMPL extends PlatformIMPL |
| | | { |
| | | |
| | | @Override |
| | | public void normalize(StringBuilder buffer) |
| | | { |
| | | // No implementation. |
| | | } |
| | | } |
| | | |
| | | |
| | | |
| | | /** |
| | | * Normalize the specified buffer. |
| | | * |
| | | * @param buffer |
| | | * The buffer to normalize. |
| | | */ |
| | | public static void normalize(StringBuilder buffer) |
| | | { |
| | | IMPL.normalize(buffer); |
| | | } |
| | | |
| | | |
| | | |
| | | /** |
| | | * Test if a platform java vendor property starts with the specified vendor |
| | | * string. |
| | | * |
| | | * @param vendor |
| | | * The vendor to check for. |
| | | * @return {@code true} if the java vendor starts with the specified vendor |
| | | * string. |
| | | */ |
| | | public static boolean isVendor(String vendor) |
| | | { |
| | | String javaVendor = System.getProperty("java.vendor"); |
| | | return javaVendor.startsWith(vendor); |
| | | } |
| | | } |
| | | |