//***************************************************************************** //* //* (c) Copyright 2002. Glub Tech, Incorporated. All Rights Reserved. //* //* $Id: KeyUtil.java 115 2009-11-26 07:42:13Z gary $ //* //***************************************************************************** package com.glub.secureftp.common; import java.io.*; import java.lang.reflect.*; import java.security.*; import java.security.cert.*; import java.security.spec.*; import java.util.*; //import com.sun.net.ssl.*; import javax.net.ssl.*; //import sun.security.x509.*; import com.glub.util.*; public class KeyUtil { // Class constants private static final String CERTIFICATE_TYPE = "X.509"; //private static final String KMFACTORY_ALGORITHM = "SunX509"; private static final String KEY_ALGORITHM = "RSA"; private static final String KEY_STORE_TYPE = "JKS"; private static final String SIG_ALGORITHM = "MD5WithRSA"; private static final int KEY_SIZE = 1024; /* static { Security.addProvider(new com.sun.net.ssl.internal.ssl.Provider()); } */ public static CertificateFactory getCertificateFactory() { CertificateFactory certFactory = null; try { certFactory = CertificateFactory.getInstance( CERTIFICATE_TYPE ); } catch (CertificateException ce) { // Leave certFactory as null } return certFactory; } public static X509Certificate[] getCertificateList( CertificateFactory f, String[] path ) throws FileNotFoundException, CertificateException { return getCertificateList( f, path, "" ); } public static X509Certificate[] getCertificateList( CertificateFactory f, String[] path, String password ) throws FileNotFoundException, CertificateException { X509Certificate[] cert = null; ArrayList certList = new ArrayList(); FileInputStream fis = null; try { for ( int i = 0; i < path.length; i++ ) { // Read all certificates from each file path fis = new FileInputStream( path[ i ] ); if ( path[i].toLowerCase().endsWith(".pfx") || path[i].toLowerCase().endsWith(".p12") ) { KeyStore ks = KeyStore.getInstance("PKCS12"); ks.load( fis, password.toCharArray() ); Enumeration e = ks.aliases(); while ( e.hasMoreElements() ) { String alias = (String)e.nextElement(); certList.add((X509Certificate)ks.getCertificate(alias)); } } else if ( path[i].toLowerCase().endsWith(".pem") ) { PEMInputStream pis = new PEMInputStream( fis ); certList.addAll( f.generateCertificates( pis ) ); pis.close(); } else { certList.addAll( f.generateCertificates( fis ) ); } Util.close( fis ); fis = null; } // Convert certificate list to an array cert = (X509Certificate[]) certList.toArray( new X509Certificate[certList.size()] ); } catch ( Exception e ) { //System.out.println( e.getMessage() ); } finally { Util.close( fis ); } return cert; } public static KeyFactory getKeyFactory() { KeyFactory keyFactory = null; try { keyFactory = KeyFactory.getInstance( KEY_ALGORITHM ); } catch (NoSuchAlgorithmException nsae) { // Leave keyFactory as null } return keyFactory; } public static KeyManagerFactory getKeyManagerFactory( KeyStore store, char[] password ) throws UnrecoverableKeyException, KeyStoreException { KeyManagerFactory kmFactory = null; try { //kmFactory = KeyManagerFactory.getInstance( KMFACTORY_ALGORITHM ); kmFactory = KeyManagerFactory.getInstance( KeyManagerFactory.getDefaultAlgorithm() ); kmFactory.init( store, password ); } catch (NoSuchAlgorithmException nsae) { // Leave kmFactory as null } return kmFactory; } public static KeyStore getKeyStore( char[] password ) throws KeyStoreException, CertificateException { KeyStore ks = null; try { ks = getKeyStore( null, password, null, null, null ); } catch (IOException ioe) { // Should not be thrown since no file is being loaded } return ks; } public static KeyStore getKeyStore( File keyFile, char[] password ) throws KeyStoreException, CertificateException, IOException { return getKeyStore( keyFile, password, null, null, null ); } public static KeyStore getKeyStore( char[] password, String keyAlias, PrivateKey privateKey, X509Certificate[] certList ) throws KeyStoreException, CertificateException { KeyStore ks = null; try { ks = getKeyStore( null, password, keyAlias, privateKey, certList ); } catch (IOException ioe) { // Should not be thrown since no file is being loaded } return ks; } public static KeyStore getKeyStore( File keyFile, char[] password, String keyAlias, PrivateKey privateKey, X509Certificate[] certList ) throws KeyStoreException, CertificateException, IOException { KeyStore store = null; InputStream is = null; try { if ( keyFile != null ) { try { is = new FileInputStream( keyFile ); } catch ( FileNotFoundException fnfe ) { // it's okay, just use null } } store = KeyStore.getInstance( KEY_STORE_TYPE ); store.load( is, password ); if (keyAlias != null && privateKey != null) { store.setKeyEntry( keyAlias, privateKey, password, certList ); } } catch (NoSuchAlgorithmException nsae) { // Leave store as null } finally { if ( is != null ) { is.close(); } } return store; } public static void writeKeyStore( KeyStore keyStore, File keyFile, char[] password ) throws IOException, KeyStoreException, NoSuchAlgorithmException, CertificateException { OutputStream os = null; try { os = new FileOutputStream( keyFile ); } catch ( FileNotFoundException fnfe ) { // it's okay, just use null } keyStore.store( os, password ); os.flush(); os.close(); } public static void addCertificate( KeyStore keyStore, X509Certificate cert ) throws KeyStoreException { keyStore.setCertificateEntry( cert.getSubjectDN().toString(), cert ); } public static boolean certificateExists( KeyStore keyStore, X509Certificate cert ) { boolean exists = false; try { exists = keyStore != null && keyStore.getCertificateAlias(cert) != null; } catch ( Exception e ) { exists = false; } return exists; } public static boolean certificateAliasExists( KeyStore keyStore, X509Certificate cert ) { return certificateAliasExists( keyStore, cert.getSubjectDN().toString() ); } public static boolean certificateAliasExists( KeyStore keyStore, String alias ) { boolean exists = false; try { exists = keyStore != null && keyStore.getCertificate(alias) != null; } catch ( Exception e ) { exists = false; } return exists; } public static void removeCertificate( KeyStore keyStore, X509Certificate cert ) throws KeyStoreException { removeCertificate( keyStore, cert.getSubjectDN().toString() ); } public static void removeCertificate( KeyStore keyStore, String alias ) throws KeyStoreException { keyStore.deleteEntry( alias ); } public static PrivateKey getPrivateKey( KeyFactory keyFactory, String keyPath ) throws FileNotFoundException, IOException, InvalidKeySpecException { return getPrivateKey( keyFactory, keyPath, "" ); } public static PrivateKey getPrivateKey( KeyFactory keyFactory, String keyPath, String password ) throws FileNotFoundException, IOException, InvalidKeySpecException { PrivateKey key = null; FileInputStream fis = null; if (keyPath != null) { fis = new FileInputStream( keyPath ); try { if ( keyPath.toLowerCase().endsWith(".pfx") || keyPath.toLowerCase().endsWith(".p12") ) { KeyStore ks = KeyStore.getInstance("PKCS12"); ks.load( fis, password.toCharArray() ); Enumeration e = ks.aliases(); while ( e.hasMoreElements() ) { String alias = (String)e.nextElement(); if ( ks.isKeyEntry(alias) ) { key = (PrivateKey)ks.getKey( alias, password.toCharArray() ); break; } } } else if ( keyPath.toLowerCase().endsWith(".pem") ) { PEMInputStream pis = new PEMInputStream( fis ); byte[] b = new byte[ pis.available() ]; pis.read( b ); pis.close(); key = keyFactory.generatePrivate( new X509EncodedKeySpec( b ) ); } else if ( keyPath.toLowerCase().endsWith(".pk8") ) { byte[] b = new byte[ fis.available() ]; fis.read( b ); key = keyFactory.generatePrivate( new PKCS8EncodedKeySpec( b ) ); } else { byte[] b = new byte[ fis.available() ]; fis.read( b ); key = keyFactory.generatePrivate( new X509EncodedKeySpec( b ) ); } } catch ( Exception e ) { //System.out.println(e.getMessage()); } finally { Util.close( fis ); } } return key; } public static boolean writeCertAndKey( CertInfo info, int days, File certFile, File keyFile ) { boolean bRet = false; FileOutputStream fileOut = null; try { /* CertAndKeyGen keypair = new CertAndKeyGen( KEY_ALGORITHM, SIG_ALGORITHM ); X500Name x500Name = new X500Name( info.getCommonName(), info.getOrganizationUnit(), info.getOrganization(), info.getCity(), info.getState(), info.getCountry() ); keypair.generate( KEY_SIZE ); PrivateKey privKey = keypair.getPrivateKey(); X509Certificate cert = keypair.getSelfCertificate( x500Name, days * 86400 ); */ String osName = System.getProperty("os.name"); String certAndKeyGenClass = "sun.security.x509.CertAndKeyGen"; if ( osName.equals("AIX") || GTOverride.getBoolean("security.ibm") ) { certAndKeyGenClass = "com.ibm.security.x509.CertAndKeyGen"; } Class certAndKey = Class.forName( certAndKeyGenClass ); Class[] certAndKeyArgs = { String.class, String.class }; Constructor certAndKeyConstructor = certAndKey.getConstructor(certAndKeyArgs); Object[] certAndKeyConstArgs = { KEY_ALGORITHM, SIG_ALGORITHM }; Object cakInstance = certAndKeyConstructor.newInstance( certAndKeyConstArgs ); String x500NameClass = "sun.security.x509.X500Name"; if ( osName.equals("AIX") || GTOverride.getBoolean("security.ibm") ) { x500NameClass = "com.ibm.security.x509.X500Name"; } Class x500Name = Class.forName( x500NameClass ); Class[] x500NameArgs = { String.class, String.class, String.class, String.class, String.class, String.class }; Constructor x500NameConstructor = x500Name.getConstructor(x500NameArgs); Object[] x500NameConstArgs = { info.getCommonName(), info.getOrganizationUnit(), info.getOrganization(), info.getCity(), info.getState(), info.getCountry() }; Object x500Instance = x500NameConstructor.newInstance( x500NameConstArgs ); Method generate = certAndKey.getMethod( "generate", new Class[] { int.class } ); generate.invoke( cakInstance, new Integer[] { new Integer(KEY_SIZE) } ); Method getPrivateKey = certAndKey.getMethod( "getPrivateKey", null ); PrivateKey privKey = (PrivateKey)getPrivateKey.invoke(cakInstance, null); Method getSelfCert = certAndKey.getMethod( "getSelfCertificate", new Class[] { x500Name, long.class} ); X509Certificate cert = (X509Certificate) getSelfCert.invoke( cakInstance, new Object[] { x500Instance, new Long(days * 86400) } ); fileOut = new FileOutputStream( keyFile ); fileOut.write( privKey.getEncoded() ); fileOut.close(); fileOut = new FileOutputStream( certFile ); fileOut.write( cert.getEncoded() ); fileOut.close(); bRet = true; } catch ( Exception e ) { if (GTOverride.getBoolean("glub.debug")) e.printStackTrace(); } finally { if ( null != fileOut ) { try { fileOut.close(); } catch ( Exception e ) {} } } return bRet; } }