You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@jmeter.apache.org by se...@apache.org on 2011/11/05 02:31:40 UTC

svn commit: r1197862 - /jmeter/trunk/src/core/org/apache/jmeter/util/keystore/JmeterKeyStore.java

Author: sebb
Date: Sat Nov  5 01:31:40 2011
New Revision: 1197862

URL: http://svn.apache.org/viewvc?rev=1197862&view=rev
Log:
Bug 52131 - Eliminate DefaultKeyStore and simplify code - part 1

Modified:
    jmeter/trunk/src/core/org/apache/jmeter/util/keystore/JmeterKeyStore.java

Modified: jmeter/trunk/src/core/org/apache/jmeter/util/keystore/JmeterKeyStore.java
URL: http://svn.apache.org/viewvc/jmeter/trunk/src/core/org/apache/jmeter/util/keystore/JmeterKeyStore.java?rev=1197862&r1=1197861&r2=1197862&view=diff
==============================================================================
--- jmeter/trunk/src/core/org/apache/jmeter/util/keystore/JmeterKeyStore.java (original)
+++ jmeter/trunk/src/core/org/apache/jmeter/util/keystore/JmeterKeyStore.java Sat Nov  5 01:31:40 2011
@@ -19,62 +19,194 @@
 package org.apache.jmeter.util.keystore;
 
 import java.io.InputStream;
+import java.security.KeyStore;
 import java.security.PrivateKey;
+import java.security.cert.Certificate;
 import java.security.cert.X509Certificate;
+import java.util.ArrayList;
+import java.util.Enumeration;
+
+import org.apache.jmeter.util.JMeterUtils;
 
 /**
  * Use this Keystore for JMeter specific KeyStores.
  *
  */
-public abstract class JmeterKeyStore {
+public class JmeterKeyStore {
+
+    private X509Certificate[][] certChains;
+    private PrivateKey[] keys;
+    private String[] names;
+    protected final KeyStore store;
+    private int last_user;
+    protected static final String KEY_STORE_START_INDEX = "https.keyStoreStartIndex";
+    protected static final String KEY_STORE_END_INDEX = "https.keyStoreEndIndex";
+    protected int startIndex;
+    protected int endIndex;
+
+    public JmeterKeyStore(String type) throws Exception {
+        this.store = KeyStore.getInstance(type);
+        startIndex = JMeterUtils.getPropDefault(KEY_STORE_START_INDEX, 0);
+        endIndex = JMeterUtils.getPropDefault(KEY_STORE_END_INDEX, 0);
+    }
 
     /**
      * Process the input stream
      */
-    public abstract void load(InputStream is, String password) throws Exception;
+    public void load(InputStream is, String pword) throws Exception {
+        store.load(is, pword.toCharArray());
+    
+        ArrayList<String> v_names = new ArrayList<String>();
+        ArrayList<PrivateKey> v_keys = new ArrayList<PrivateKey>();
+        ArrayList<X509Certificate[]> v_certChains = new ArrayList<X509Certificate[]>();
+    
+        if (null != is){ // No point checking an empty keystore
+            PrivateKey _key = null;
+            int index = 0;
+            Enumeration<String> aliases = store.aliases();
+            while (aliases.hasMoreElements()) {
+                String alias = aliases.nextElement();
+                if (store.isKeyEntry(alias)) {
+                    if ((index >= startIndex && index <= endIndex)) {
+                        _key = (PrivateKey) store.getKey(alias, pword.toCharArray());
+                        if (null == _key) {
+                            throw new Exception("No key found for alias: " + alias); // Should not happen
+                        }
+                        Certificate[] chain = store.getCertificateChain(alias);
+                        if (null == chain) {
+                            throw new Exception("No certificate chain found for alias: " + alias);
+                        }
+                        v_names.add(alias);
+                        v_keys.add(_key);
+                        X509Certificate[] x509certs = new X509Certificate[chain.length];
+                        for (int i = 0; i < x509certs.length; i++) {
+                            x509certs[i] = (X509Certificate)chain[i];
+                        }
+                        v_certChains.add(x509certs);
+                    }
+                }
+                index++;
+            }
+    
+            if (null == _key) {
+                throw new Exception("No key(s) found");
+            }
+        }
+    
+        /*
+         * Note: if is == null, the arrays will be empty
+         */
+        int v_size = v_names.size();
+    
+        this.names = new String[v_size];
+        this.names = v_names.toArray(names);
+    
+        this.keys = new PrivateKey[v_size];
+        this.keys = v_keys.toArray(keys);
+    
+        this.certChains = new X509Certificate[v_size][];
+        this.certChains = v_certChains.toArray(certChains);
+    }
+
 
     /**
      * Get the ordered certificate chain for a specific alias.
      */
-    public abstract X509Certificate[] getCertificateChain(String alias);
+    public final X509Certificate[] getCertificateChain(String alias) {
+        int entry = findAlias(alias);
+        if (entry >=0) {
+            return this.certChains[entry];
+        }
+        return null;
+    }
 
     /**
      * Get the next or only alias.
      * @return the next or only alias.
      */
-    public abstract String getAlias();
+    public final String getAlias() {
+        int length = this.names.length;
+        if (length == 0) { // i.e. is == null
+            return null;
+        }
+        return this.names[getNextIndex(length)];
+    }
 
-    public abstract int getAliasCount();
+    public int getAliasCount() {
+        return this.names.length;
+    }
 
-    public abstract String getAlias(int index);
+    public final String getAlias(int index) {
+        int length = this.names.length;
+        if (length == 0 && index == 0) { // i.e. is == null
+            return null;
+        }
+        if (index >= length || index < 0) {
+            throw new ArrayIndexOutOfBoundsException(index);
+        }
+        return this.names[index];
+    }
 
     /**
      * Return the private Key for a specific alias
      */
-    public abstract PrivateKey getPrivateKey(String alias);
+    public final PrivateKey getPrivateKey(String alias) {
+        int entry = findAlias(alias);
+        if (entry >=0) {
+            return this.keys[entry];
+        }
+        return null;
+    }
 
     public static final JmeterKeyStore getInstance(String type) throws Exception {
         // JAVA 1.4 now handles all keystore types, so just use default
-        return new DefaultKeyStore(type);
+        return new JmeterKeyStore(type);
     }
     
     /**
      * @param startIndex the startIndex to set
      */
-    public abstract void setAliasStartIndex(int startIndex);
+    public void setAliasStartIndex(int startIndex) {
+        this.startIndex = startIndex;
+    }
 
     /**
      * @return the endIndex
      */
-    public abstract int getAliasEndIndex();
+    public int getAliasEndIndex() {
+        return endIndex;
+    }
 
     /**
      * @param endIndex the endIndex to set
      */
-    public abstract void setAliasEndIndex(int endIndex);
-    
+    public void setAliasEndIndex(int endIndex) {
+        this.endIndex = endIndex;
+    }
     /**
-     * @return int index of start alias in keystore
+     * @return the startIndex
      */
-    public abstract int getAliasStartIndex();
+    public int getAliasStartIndex() {
+        return startIndex;
+    }
+
+    private int findAlias(String alias) {
+        for(int i = 0; i < names.length; i++) {
+            if (alias.equals(names[i])){
+                return i;
+            }
+        }
+        return -1;
+    }
+
+    private int getNextIndex(int length) {
+        synchronized(this) {
+            last_user ++;
+            if (last_user >= length) {
+                last_user = 0;
+            }
+            return last_user;
+        }
+    }
+
 }
\ No newline at end of file