You are viewing a plain text version of this content. The canonical link for it is here.
Posted to ftpserver-commits@incubator.apache.org by ng...@apache.org on 2007/08/15 21:30:49 UTC

svn commit: r566350 - /incubator/ftpserver/trunk/core/src/java/org/apache/ftpserver/ssl/DefaultSsl.java

Author: ngn
Date: Wed Aug 15 14:30:48 2007
New Revision: 566350

URL: http://svn.apache.org/viewvc?view=rev&rev=566350
Log:
Implement using a seperate trust store (FTPSERVER-58)

Modified:
    incubator/ftpserver/trunk/core/src/java/org/apache/ftpserver/ssl/DefaultSsl.java

Modified: incubator/ftpserver/trunk/core/src/java/org/apache/ftpserver/ssl/DefaultSsl.java
URL: http://svn.apache.org/viewvc/incubator/ftpserver/trunk/core/src/java/org/apache/ftpserver/ssl/DefaultSsl.java?view=diff&rev=566350&r1=566349&r2=566350
==============================================================================
--- incubator/ftpserver/trunk/core/src/java/org/apache/ftpserver/ssl/DefaultSsl.java (original)
+++ incubator/ftpserver/trunk/core/src/java/org/apache/ftpserver/ssl/DefaultSsl.java Wed Aug 15 14:30:48 2007
@@ -21,10 +21,12 @@
 
 import java.io.File;
 import java.io.FileInputStream;
+import java.io.IOException;
 import java.security.GeneralSecurityException;
 import java.security.KeyStore;
 import java.util.HashMap;
 
+import javax.net.ssl.KeyManager;
 import javax.net.ssl.KeyManagerFactory;
 import javax.net.ssl.SSLContext;
 import javax.net.ssl.TrustManagerFactory;
@@ -44,15 +46,20 @@
     private final Logger LOG = LoggerFactory.getLogger(DefaultSsl.class);
     
     private File keystoreFile = new File("./res/.keystore");
-    private String keystorePass = "password";   // TODO should we really default this value?
+    private String keystorePass;
     private String keystoreType = "JKS";
     private String keystoreAlgorithm = "SunX509";
+
+    private File trustStoreFile;
+    private String trustStorePass;
+    private String trustStoreType = "JKS";
+    private String trustStoreAlgorithm = "SunX509";
     
     private String sslProtocol = "TLS";
     private ClientAuth clientAuthReqd = ClientAuth.NONE;
-    private String keyPass = "password";   // TODO should we really default this value?
+    private String keyPass;
+
 
-    private KeyStore keyStore;
     private KeyManagerFactory keyManagerFactory;
     private TrustManagerFactory trustManagerFactory;
     
@@ -60,20 +67,41 @@
 
     private String[] enabledCipherSuites;
     
+    public File getKeystoreFile() {
+        return keystoreFile;
+    }
+    
     public void setKeystoreFile(File keyStoreFile) {
         this.keystoreFile = keyStoreFile;
     }
     
+    public String getKeystorePassword() {
+        return keystorePass;
+    }
+    
     public void setKeystorePassword(String keystorePass) {
         this.keystorePass = keystorePass;
     }
     
+    public String getKeystoreType() {
+        return keystoreType;
+    }
+    
     public void setKeystoreType(String keystoreType) {
         this.keystoreType = keystoreType;
     }
     
+    public String getKeystoreAlgorithm() {
+        return keystoreAlgorithm;
+    }
+    
     public void setKeystoreAlgorithm(String keystoreAlgorithm) {
         this.keystoreAlgorithm = keystoreAlgorithm;
+    
+    }
+    
+    public String getSslProtocol() {
+        return sslProtocol;
     }
     
     public void setSslProtocol(String sslProtocol) {
@@ -91,10 +119,60 @@
         }
     }
     
+    public String getKeyPassword() {
+        return keyPass;
+    }
+    
     public void setKeyPassword(String keyPass) {
         this.keyPass = keyPass;
     }
     
+    public File getTruststoreFile() {
+        return trustStoreFile;
+    }
+    
+    public void setTruststoreFile(File trustStoreFile) {
+        this.trustStoreFile = trustStoreFile;
+    }
+    
+    public String getTruststorePassword() {
+        return trustStorePass;
+    }
+    
+    public void setTruststorePassword(String trustStorePass) {
+        this.trustStorePass = trustStorePass;
+    }
+    
+    public String getTruststoreType() {
+        return trustStoreType;
+    }
+    
+    public void setTruststoreType(String trustStoreType) {
+        this.trustStoreType = trustStoreType;
+    }
+    
+    public String getTruststoreAlgorithm() {
+        return trustStoreAlgorithm;
+    }
+    
+    public void setTruststoreAlgorithm(String trustStoreAlgorithm) {
+        this.trustStoreAlgorithm = trustStoreAlgorithm;
+    
+    }
+
+    private KeyStore loadStore(File storeFile, String storeType, String storePass) throws IOException, GeneralSecurityException {
+        FileInputStream fin = null;
+        try {
+            fin = new FileInputStream(storeFile);
+            KeyStore store = KeyStore.getInstance(storeType);
+            store.load(fin, storePass.toCharArray());
+            
+            return store;
+        }
+        finally {
+            IoUtils.close(fin);
+        }
+    }
     
     /**
      * Configure secure server related properties. 
@@ -103,14 +181,13 @@
         
         try {
             // initialize keystore
-            FileInputStream fin = null;
-            try {
-                fin = new FileInputStream(keystoreFile);
-                keyStore = KeyStore.getInstance(keystoreType);
-                keyStore.load(fin, keystorePass.toCharArray());
-            }
-            finally {
-                IoUtils.close(fin);
+            KeyStore keyStore = loadStore(keystoreFile, keystoreType, keystorePass);
+            
+            KeyStore trustStore;
+            if(trustStoreFile != null) {
+                trustStore = loadStore(trustStoreFile, trustStoreType, trustStorePass);
+            } else {
+                trustStore = keyStore;
             }
             
             // initialize key manager factory
@@ -118,8 +195,8 @@
             keyManagerFactory.init(keyStore, keyPass.toCharArray());
             
             // initialize trust manager factory
-            trustManagerFactory = TrustManagerFactory.getInstance(keystoreAlgorithm);
-            trustManagerFactory.init(keyStore);
+            trustManagerFactory = TrustManagerFactory.getInstance(trustStoreAlgorithm);
+            trustManagerFactory.init(trustStore);
             
             // create ssl context map - the key is the 
             // SSL protocol and the value is SSLContext.
@@ -131,7 +208,7 @@
         }
     }
     
-    private void lazyInit() {
+    private synchronized void lazyInit() {
         if(keyManagerFactory == null) {
             init();
         }
@@ -156,7 +233,19 @@
         
         // create SSLContext
         ctx = SSLContext.getInstance(protocol);
-        ctx.init(keyManagerFactory.getKeyManagers(), 
+        
+        KeyManager[] keyManagers = keyManagerFactory.getKeyManagers();
+        
+        // wrap key managers to allow us to control their behavior
+        // FTPSERVER-93, currently not working as described in the issue
+        //for (int i = 0; i < keyManagers.length; i++) {
+        //  if(keyManagers[i] instanceof X509KeyManager) {
+        //      X509KeyManager keyManager = (X509KeyManager) keyManagers[i];
+        //      keyManagers[i] = new JSSEKeyManager(keyManager, keyAlias);
+        //  }
+        //} 
+        
+        ctx.init(keyManagers, 
                  trustManagerFactory.getTrustManagers(), 
                  null);
 
@@ -165,12 +254,6 @@
         
         return ctx;
     }
-    
-    /**
-     * Dispose - does nothing.
-     */
-    public void dispose() {
-    }
 
     public ClientAuth getClientAuth() {
         return clientAuthReqd;
@@ -187,4 +270,23 @@
     public void setEnabledCipherSuites(String[] enabledCipherSuites) {
         this.enabledCipherSuites = enabledCipherSuites;
     }
+
+    /**
+     * Get the server key alias to be used for SSL communication
+     * @return The alias, or null if none is set
+     */
+//    public String getKeyAlias() {
+//        return keyAlias;
+//    }
+
+    /**
+     * Set the alias for the key to be used for SSL communication.
+     * If the specified key store contains multiple keys, this 
+     * alias can be set to select a specific key.
+     * @param keyAlias The alias to use, or null if JSSE should
+     *          be allowed to choose the key.
+     */
+//    public void setKeyAlias(String keyAlias) {
+//        this.keyAlias = keyAlias;
+//    }
 }