Re: svn commit: r1187840 - in /jakarta/jmeter/trunk: bin/ src/core/org/apache/jmeter/util/ src/core/org/apache/jmeter/util/keystore/ xdocs/
sebb <[email protected]> Sun, 23 Oct 2011 12:01:36 +0100
| Newsgroups | gmane.comp.jakarta.cactus.devel |
|---|---|
| Message-ID | <CAOGo0VbDtA+89ude9RaeROFAB0HOOHMJA210jQc9kuor-5JJAQ@mail.gmail.com> |
On 23 October 2011 11:53, Philippe Mouawad <[email protected]> wro= te: > I looked in a bit more detail, > static is needed Not if one moves the field to the WrappedX509KeyManager class, which is what I will do. > I think AtomicInteger won't do it because we need to increment and % > aliasCount in the same time, don't know if we can do that =A0so maybe jus= t a > custom lock for this static field would do it. > On Sun, Oct 23, 2011 at 12:49 PM, sebb <[email protected]> wrote: > >> On 23 October 2011 11:38, Philippe Mouawad <[email protected]> >> wrote: >> > Hello, >> > Regarding this last commit, =A0I think there is an issue in last_user >> either >> > being static or being synchronized on this. >> > >> > In my opinion, as it seems JsseSSLManager is a singleton, last_user >> should >> > be instance variable. >> > If it's not the case, then synchronized block in getNextIndex should b= e >> on >> > JsseSSLManager.class or field should use AtomicInteger . >> >> Good catch indeed! >> >> I originally was going to use AtomicInteger, but would still have had >> to protect the wrap-around code. >> >> I'll fix it shortly. >> >> > Regards >> > Philippe >> > >> > On Sun, Oct 23, 2011 at 3:50 AM, <[email protected]> wrote: >> > >> >> Author: sebb >> >> Date: Sun Oct 23 01:50:55 2011 >> >> New Revision: 1187840 >> >> >> >> URL: http://svn.apache.org/viewvc?rev=3D1187840&view=3Drev >> >> Log: >> >> Bug 52033 - Allowing multiple certificates (JKS) >> >> >> >> Modified: >> >> =A0 =A0jakarta/jmeter/trunk/bin/jmeter.properties >> >> >> =A0jakarta/jmeter/trunk/src/core/org/apache/jmeter/util/JsseSSLManager.j= ava >> >> =A0 =A0jakarta/jmeter/trunk/src/core/org/apache/jmeter/util/SSLManage= r.java >> >> >> >> >> =A0jakarta/jmeter/trunk/src/core/org/apache/jmeter/util/keystore/Default= KeyStore.java >> >> >> >> >> =A0jakarta/jmeter/trunk/src/core/org/apache/jmeter/util/keystore/JmeterK= eyStore.java >> >> =A0 =A0jakarta/jmeter/trunk/xdocs/changes.xml >> >> >> >> Modified: jakarta/jmeter/trunk/bin/jmeter.properties >> >> URL: >> >> >> http://svn.apache.org/viewvc/jakarta/jmeter/trunk/bin/jmeter.properties?= rev=3D1187840&r1=3D1187839&r2=3D1187840&view=3Ddiff >> >> >> >> >> =3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D= =3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D= =3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D= =3D=3D=3D=3D >> >> --- jakarta/jmeter/trunk/bin/jmeter.properties (original) >> >> +++ jakarta/jmeter/trunk/bin/jmeter.properties Sun Oct 23 01:50:55 20= 11 >> >> @@ -78,6 +78,11 @@ xml.parser=3Dorg.apache.xerces.parsers.SAX >> >> =A0# set the value to 'false' to reset the SSL context each iteration >> >> =A0#https.use.cached.ssl.context=3Dtrue >> >> >> >> +# Start and end index to be used with keystores with many entries >> >> +# The default is to use entry 0, i.e. the first >> >> +#https.keyStoreStartIndex=3D0 >> >> +#https.keyStoreEndIndex=3D0 >> >> + >> >> >> >> >> =A0#--------------------------------------------------------------------= ------- >> >> =A0# Look and Feel configuration >> >> >> >> >> =A0#--------------------------------------------------------------------= ------- >> >> >> >> Modified: >> >> jakarta/jmeter/trunk/src/core/org/apache/jmeter/util/JsseSSLManager.j= ava >> >> URL: >> >> >> http://svn.apache.org/viewvc/jakarta/jmeter/trunk/src/core/org/apache/jm= eter/util/JsseSSLManager.java?rev=3D1187840&r1=3D1187839&r2=3D1187840&view= =3Ddiff >> >> >> >> >> =3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D= =3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D= =3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D= =3D=3D=3D=3D >> >> --- >> >> jakarta/jmeter/trunk/src/core/org/apache/jmeter/util/JsseSSLManager.j= ava >> >> (original) >> >> +++ >> >> jakarta/jmeter/trunk/src/core/org/apache/jmeter/util/JsseSSLManager.j= ava >> Sun >> >> Oct 23 01:50:55 2011 >> >> @@ -70,6 +70,9 @@ public class JsseSSLManager extends SSLM >> >> >> >> =A0 =A0 private static final int cps; >> >> >> >> + =A0 =A0//@GuardedBy("this") >> >> + =A0 =A0private static int =A0last_user; >> >> + >> >> =A0 =A0 static { >> >> =A0 =A0 =A0 =A0 log.info("Using default SSL protocol: "+DEFAULT_SSL_P= ROTOCOL); >> >> =A0 =A0 =A0 =A0 log.info("SSL session context: "+(SHARED_SESSION_CONT= EXT ? >> >> "shared" : "per-thread")); >> >> @@ -314,8 +317,12 @@ public class JsseSSLManager extends SSLM >> >> =A0 =A0 =A0 =A0 =A0*/ >> >> =A0 =A0 =A0 =A0 public String[] getClientAliases(String keyType, Prin= cipal[] >> >> issuers) { >> >> =A0 =A0 =A0 =A0 =A0 =A0 log.debug("WrappedX509Manager: getClientAlias= es: "); >> >> - =A0 =A0 =A0 =A0 =A0 =A0log.debug(this.store.getAlias()); >> >> - =A0 =A0 =A0 =A0 =A0 =A0return new String[] { this.store.getAlias() = }; >> >> + =A0 =A0 =A0 =A0 =A0 =A0int count =3D this.store.getAliasCount(); >> >> + =A0 =A0 =A0 =A0 =A0 =A0String[] aliases =3D new String[count]; >> >> + =A0 =A0 =A0 =A0 =A0 =A0for(int i =3D 0; i < aliases.length; i++) { >> >> + =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0aliases[i] =3D this.store.getAlias(i= ); >> >> + =A0 =A0 =A0 =A0 =A0 =A0} >> >> + =A0 =A0 =A0 =A0 =A0 =A0 return aliases; >> >> =A0 =A0 =A0 =A0 } >> >> >> >> =A0 =A0 =A0 =A0 /** >> >> @@ -343,7 +350,7 @@ public class JsseSSLManager extends SSLM >> >> =A0 =A0 =A0 =A0 =A0*/ >> >> =A0 =A0 =A0 =A0 public X509Certificate[] getCertificateChain(String a= lias) { >> >> =A0 =A0 =A0 =A0 =A0 =A0 log.debug("WrappedX509Manager: getCertificate= Chain(" + alias >> + >> >> ")"); >> >> - =A0 =A0 =A0 =A0 =A0 =A0return this.store.getCertificateChain(); >> >> + =A0 =A0 =A0 =A0 =A0 =A0return this.store.getCertificateChain(alias)= ; >> >> =A0 =A0 =A0 =A0 } >> >> >> >> =A0 =A0 =A0 =A0 /** >> >> @@ -354,8 +361,9 @@ public class JsseSSLManager extends SSLM >> >> =A0 =A0 =A0 =A0 =A0* @return The PrivateKey value >> >> =A0 =A0 =A0 =A0 =A0*/ >> >> =A0 =A0 =A0 =A0 public PrivateKey getPrivateKey(String alias) { >> >> - =A0 =A0 =A0 =A0 =A0 =A0log.debug("WrappedX509Manager: getPrivateKey= : " + >> >> this.store.getPrivateKey()); >> >> - =A0 =A0 =A0 =A0 =A0 =A0return this.store.getPrivateKey(); >> >> + =A0 =A0 =A0 =A0 =A0 =A0PrivateKey privateKey =3D this.store.getPriv= ateKey(alias); >> >> + =A0 =A0 =A0 =A0 =A0 =A0log.debug("WrappedX509Manager: getPrivateKey= : " + >> privateKey); >> >> + =A0 =A0 =A0 =A0 =A0 =A0return privateKey; >> >> =A0 =A0 =A0 =A0 } >> >> >> >> =A0 =A0 =A0 =A0 /** >> >> @@ -372,14 +380,28 @@ public class JsseSSLManager extends SSLM >> >> =A0 =A0 =A0 =A0 =A0* @see javax.net.ssl.X509KeyManager#chooseClientAl= ias(String[], >> >> Principal[], Socket) >> >> =A0 =A0 =A0 =A0 =A0*/ >> >> =A0 =A0 =A0 =A0 public String chooseClientAlias(String[] keyType, Pri= ncipal[] >> >> issuers, Socket socket) { >> >> - =A0 =A0 =A0 =A0 =A0 =A0String alias =3D this.store.getAlias(); >> >> - =A0 =A0 =A0 =A0 =A0 =A0log.debug("ClientAlias: " + alias); >> >> + =A0 =A0 =A0 =A0 =A0 =A0log.debug("keyType: " + keyType[0]); >> >> + =A0 =A0 =A0 =A0 =A0 =A0int aliasCount =3D this.store.getAliasCount(= ); >> >> + =A0 =A0 =A0 =A0 =A0 =A0String alias =3D >> this.store.getAlias(getNextIndex(aliasCount)); >> >> =A0 =A0 =A0 =A0 =A0 =A0 if (alias =3D=3D null || alias.length() =3D= =3D 0) { >> >> =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 log.debug("ClientAlias not found."); >> >> =A0 =A0 =A0 =A0 =A0 =A0 } >> >> =A0 =A0 =A0 =A0 =A0 =A0 return alias; >> >> =A0 =A0 =A0 =A0 } >> >> >> >> + =A0 =A0 =A0 =A0private int getNextIndex(int aliasCount) { >> >> + =A0 =A0 =A0 =A0 =A0 =A0if (aliasCount =3D=3D 1) { >> >> + =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0return 0; >> >> + =A0 =A0 =A0 =A0 =A0 =A0} >> >> + =A0 =A0 =A0 =A0 =A0 =A0synchronized(this) { >> >> + =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0last_user ++; >> >> + =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0if (last_user >=3D aliasCount) { >> >> + =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0last_user =3D 0; >> >> + =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0} >> >> + =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0return last_user; >> >> + =A0 =A0 =A0 =A0 =A0 =A0} >> >> + =A0 =A0 =A0 =A0} >> >> + >> >> =A0 =A0 =A0 =A0 /** >> >> =A0 =A0 =A0 =A0 =A0* Choose the server alias for the SSLServerSockets= . This are >> not >> >> used >> >> =A0 =A0 =A0 =A0 =A0* in JMeter. >> >> >> >> Modified: >> >> jakarta/jmeter/trunk/src/core/org/apache/jmeter/util/SSLManager.java >> >> URL: >> >> >> http://svn.apache.org/viewvc/jakarta/jmeter/trunk/src/core/org/apache/jm= eter/util/SSLManager.java?rev=3D1187840&r1=3D1187839&r2=3D1187840&view=3Ddi= ff >> >> >> >> >> =3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D= =3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D= =3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D= =3D=3D=3D=3D >> >> --- jakarta/jmeter/trunk/src/core/org/apache/jmeter/util/SSLManager.j= ava >> >> (original) >> >> +++ jakarta/jmeter/trunk/src/core/org/apache/jmeter/util/SSLManager.j= ava >> >> Sun Oct 23 01:50:55 2011 >> >> @@ -64,7 +64,7 @@ public abstract class SSLManager { >> >> =A0 =A0 private static final Provider sslProvider =3D null; >> >> >> >> =A0 =A0 /** Cache the KeyStore instance */ >> >> - =A0 =A0private JmeterKeyStore keyStore; >> >> + =A0 =A0private volatile JmeterKeyStore keyStore; >> >> >> >> =A0 =A0 /** Cache the TrustStore instance - null if no truststore nam= e was >> >> provided */ >> >> =A0 =A0 private KeyStore trustStore =3D null; >> >> @@ -126,7 +126,9 @@ public abstract class SSLManager { >> >> =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 if (initStore.exists()) { >> >> =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 fileInputStream =3D new FileI= nputStream(initStore); >> >> =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 this.keyStore.load(fileInputS= tream, getPassword()); >> >> - =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0log.info("Keystore loaded OK= from file, found >> alias: >> >> "+keyStore.getAlias()); >> >> + =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0if (log.isInfoEnabled()) { >> >> + =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0log.info("Total of "= + >> keyStore.getAliasCount() + >> >> " aliases loaded OK from keystore"); >> >> + =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0} >> >> =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 } else { >> >> =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 log.warn("Keystore file not f= ound, loading empty >> >> keystore"); >> >> =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 this.defaultpw =3D ""; // Ens= ure not null >> >> >> >> Modified: >> >> >> jakarta/jmeter/trunk/src/core/org/apache/jmeter/util/keystore/DefaultKey= Store.java >> >> URL: >> >> >> http://svn.apache.org/viewvc/jakarta/jmeter/trunk/src/core/org/apache/jm= eter/util/keystore/DefaultKeyStore.java?rev=3D1187840&r1=3D1187839&r2=3D118= 7840&view=3Ddiff >> >> >> >> >> =3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D= =3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D= =3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D= =3D=3D=3D=3D >> >> --- >> >> >> jakarta/jmeter/trunk/src/core/org/apache/jmeter/util/keystore/DefaultKey= Store.java >> >> (original) >> >> +++ >> >> >> jakarta/jmeter/trunk/src/core/org/apache/jmeter/util/keystore/DefaultKey= Store.java >> >> Sun Oct 23 01:50:55 2011 >> >> @@ -23,21 +23,35 @@ import java.security.KeyStore; >> >> =A0import java.security.PrivateKey; >> >> =A0import java.security.cert.Certificate; >> >> =A0import java.security.cert.X509Certificate; >> >> +import java.util.ArrayList; >> >> =A0import java.util.Enumeration; >> >> >> >> +import org.apache.jmeter.util.JMeterUtils; >> >> + >> >> =A0/** >> >> =A0* Use this Keystore to wrap the normal KeyStore implementation. >> >> =A0* >> >> =A0*/ >> >> =A0public class DefaultKeyStore extends JmeterKeyStore { >> >> - =A0 =A0private X509Certificate[] certChain; >> >> + =A0 =A0private X509Certificate[][] certChains; >> >> >> >> - =A0 =A0private PrivateKey key; >> >> + =A0 =A0private PrivateKey[] keys; >> >> >> >> - =A0 =A0private String alias; >> >> + =A0 =A0private String[] names; >> >> >> >> =A0 =A0 private final KeyStore store; >> >> >> >> + =A0 =A0private static final String KEY_STORE_START_INDEX =3D >> >> "https.keyStoreStartIndex"; // $NON-NLS-1$ >> >> + =A0 =A0private static final String KEY_STORE_END_INDEX =A0 =3D >> >> "https.keyStoreEndIndex"; // $NON-NLS-1$ >> >> + >> >> + =A0 =A0private static final int startIndex; >> >> + =A0 =A0private static final int endIndex; >> >> + >> >> + =A0 =A0static { >> >> + =A0 =A0 =A0 =A0startIndex =3D JMeterUtils.getPropDefault(KEY_STORE_= START_INDEX, >> 0); >> >> + =A0 =A0 =A0 =A0endIndex =3D JMeterUtils.getPropDefault(KEY_STORE_EN= D_INDEX, 0); >> >> + =A0 =A0} >> >> + >> >> =A0 =A0 public DefaultKeyStore(String type) throws Exception { >> >> =A0 =A0 =A0 =A0 this.store =3D KeyStore.getInstance(type); >> >> =A0 =A0 } >> >> @@ -46,54 +60,96 @@ public class DefaultKeyStore extends Jme >> >> =A0 =A0 @Override >> >> =A0 =A0 public void load(InputStream is, String pword) throws Excepti= on { >> >> =A0 =A0 =A0 =A0 store.load(is, pword.toCharArray()); >> >> - =A0 =A0 =A0 =A0PrivateKey _key =3D null; >> >> - =A0 =A0 =A0 =A0X509Certificate[] _certChain =3D null; >> >> >> >> - =A0 =A0 =A0 =A0if (null !=3D is){ // No point checking an empty key= store >> >> + =A0 =A0 =A0 =A0ArrayList<String> v_names =3D new ArrayList<String>(= ); >> >> + =A0 =A0 =A0 =A0ArrayList<PrivateKey> v_keys =3D new ArrayList<Priva= teKey>(); >> >> + =A0 =A0 =A0 =A0ArrayList<X509Certificate[]> v_certChains =3D new >> >> ArrayList<X509Certificate[]>(); >> >> >> >> + =A0 =A0 =A0 =A0if (null !=3D is){ // No point checking an empty key= store >> >> + =A0 =A0 =A0 =A0 =A0 =A0PrivateKey _key =3D null; >> >> + =A0 =A0 =A0 =A0 =A0 =A0int index =3D 0; >> >> =A0 =A0 =A0 =A0 =A0 =A0 Enumeration<String> aliases =3D store.aliases= (); >> >> =A0 =A0 =A0 =A0 =A0 =A0 while (aliases.hasMoreElements()) { >> >> - =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0this.alias =3D aliases.nextElement()= ; >> >> + =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0String alias =3D aliases.nextElement= (); >> >> =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 if (store.isKeyEntry(alias)) { >> >> - =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0_key =3D (PrivateKey) store.= getKey(alias, >> >> pword.toCharArray()); >> >> - =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0Certificate[] chain =3D >> >> store.getCertificateChain(alias); >> >> - =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0_certChain =3D new X509Certi= ficate[chain.length]; >> >> - >> >> - =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0for (int i =3D 0; i < chain.= length; i++) { >> >> - =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0_certChain[i] =3D (X= 509Certificate) chain[i]; >> >> + =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0if ((index >=3D startIndex &= & index <=3D endIndex)) { >> >> + =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0_key =3D (PrivateKey= ) store.getKey(alias, >> >> pword.toCharArray()); >> >> + =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0if (null =3D=3D _key= ) { >> >> + =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0throw new Ex= ception("No key found for >> alias: " >> >> + alias); // Should not happen >> >> + =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0} >> >> + =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0Certificate[] chain = =3D >> >> store.getCertificateChain(alias); >> >> + =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0if (null =3D=3D chai= n) { >> >> + =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0throw new Ex= ception("No certificate chain >> >> found for alias: " + alias); >> >> + =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0} >> >> + =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0v_names.add(alias); >> >> + =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0v_keys.add(_key); >> >> + =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0v_certChains.add((X5= 09Certificate[]) chain); >> >> =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 } >> >> - >> >> - =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0break; >> >> =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 } >> >> + =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0index++; >> >> =A0 =A0 =A0 =A0 =A0 =A0 } >> >> >> >> =A0 =A0 =A0 =A0 =A0 =A0 if (null =3D=3D _key) { >> >> - =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0throw new Exception("No key found"); >> >> - =A0 =A0 =A0 =A0 =A0 =A0} >> >> - =A0 =A0 =A0 =A0 =A0 =A0if (null =3D=3D _certChain) { >> >> - =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0throw new Exception("No certificate = chain found"); >> >> + =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0throw new Exception("No key(s) found= "); >> >> =A0 =A0 =A0 =A0 =A0 =A0 } >> >> =A0 =A0 =A0 =A0 } >> >> >> >> - =A0 =A0 =A0 =A0this.key =3D _key; >> >> - =A0 =A0 =A0 =A0this.certChain =3D _certChain; >> >> + =A0 =A0 =A0 =A0/* >> >> + =A0 =A0 =A0 =A0 * Note: if is =3D=3D null, the arrays will be empty >> >> + =A0 =A0 =A0 =A0 */ >> >> + =A0 =A0 =A0 =A0int v_size =3D v_names.size(); >> >> + >> >> + =A0 =A0 =A0 =A0this.names =3D new String[v_size]; >> >> + =A0 =A0 =A0 =A0this.names =3D v_names.toArray(names); >> >> + >> >> + =A0 =A0 =A0 =A0this.keys =3D new PrivateKey[v_size]; >> >> + =A0 =A0 =A0 =A0this.keys =3D v_keys.toArray(keys); >> >> + >> >> + =A0 =A0 =A0 =A0this.certChains =3D new X509Certificate[v_size][]; >> >> + =A0 =A0 =A0 =A0this.certChains =3D v_certChains.toArray(certChains)= ; >> >> =A0 =A0 } >> >> >> >> - =A0 =A0/** {@inheritDoc} */ >> >> =A0 =A0 @Override >> >> - =A0 =A0public final X509Certificate[] getCertificateChain() { >> >> - =A0 =A0 =A0 =A0return this.certChain; >> >> + =A0 =A0public final X509Certificate[] getCertificateChain(String al= ias) { >> >> + =A0 =A0 =A0 =A0int entry =3D findAlias(alias); >> >> + =A0 =A0 =A0 =A0if (entry >=3D0) { >> >> + =A0 =A0 =A0 =A0 =A0 =A0return this.certChains[entry]; >> >> + =A0 =A0 =A0 =A0} >> >> + =A0 =A0 =A0 =A0return null; >> >> =A0 =A0 } >> >> >> >> - =A0 =A0/** {@inheritDoc} */ >> >> =A0 =A0 @Override >> >> - =A0 =A0public final PrivateKey getPrivateKey() { >> >> - =A0 =A0 =A0 =A0return this.key; >> >> + =A0 =A0public final PrivateKey getPrivateKey(String alias) { >> >> + =A0 =A0 =A0 =A0int entry =3D findAlias(alias); >> >> + =A0 =A0 =A0 =A0if (entry >=3D0) { >> >> + =A0 =A0 =A0 =A0 =A0 =A0return this.keys[entry]; >> >> + =A0 =A0 =A0 =A0} >> >> + =A0 =A0 =A0 =A0return null; >> >> =A0 =A0 } >> >> >> >> - =A0 =A0/** {@inheritDoc} */ >> >> =A0 =A0 @Override >> >> - =A0 =A0public final String getAlias() { >> >> - =A0 =A0 =A0 =A0return this.alias; >> >> + =A0 =A0public final String getAlias(int index) { >> >> + =A0 =A0 =A0 =A0int length =3D this.names.length; >> >> + =A0 =A0 =A0 =A0if (length =3D=3D 0 && index =3D=3D 0) { // i.e. is = =3D=3D null >> >> + =A0 =A0 =A0 =A0 =A0 =A0return null; >> >> + =A0 =A0 =A0 =A0} >> >> + =A0 =A0 =A0 =A0if (index >=3D length || index < 0) { >> >> + =A0 =A0 =A0 =A0 =A0 =A0throw new ArrayIndexOutOfBoundsException(ind= ex); >> >> + =A0 =A0 =A0 =A0} >> >> + =A0 =A0 =A0 =A0return this.names[index]; >> >> + =A0 =A0} >> >> + >> >> + =A0 =A0@Override >> >> + =A0 =A0public int getAliasCount() { >> >> + =A0 =A0 =A0 =A0return this.names.length; >> >> + =A0 =A0} >> >> + >> >> + =A0 =A0private int findAlias(String alias) { >> >> + =A0 =A0 =A0 =A0for(int i =3D 0; i < names.length; i++) { >> >> + =A0 =A0 =A0 =A0 =A0 =A0if (alias.equals(names[i])){ >> >> + =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0return i; >> >> + =A0 =A0 =A0 =A0 =A0 =A0} >> >> + =A0 =A0 =A0 =A0} >> >> + =A0 =A0 =A0 =A0return -1; >> >> =A0 =A0 } >> >> =A0} >> >> >> >> Modified: >> >> >> jakarta/jmeter/trunk/src/core/org/apache/jmeter/util/keystore/JmeterKeyS= tore.java >> >> URL: >> >> >> http://svn.apache.org/viewvc/jakarta/jmeter/trunk/src/core/org/apache/jm= eter/util/keystore/JmeterKeyStore.java?rev=3D1187840&r1=3D1187839&r2=3D1187= 840&view=3Ddiff >> >> >> >> >> =3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D= =3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D= =3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D= =3D=3D=3D=3D >> >> --- >> >> >> jakarta/jmeter/trunk/src/core/org/apache/jmeter/util/keystore/JmeterKeyS= tore.java >> >> (original) >> >> +++ >> >> >> jakarta/jmeter/trunk/src/core/org/apache/jmeter/util/keystore/JmeterKeyS= tore.java >> >> Sun Oct 23 01:50:55 2011 >> >> @@ -34,16 +34,18 @@ public abstract class JmeterKeyStore { >> >> =A0 =A0 public abstract void load(InputStream is, String password) th= rows >> >> Exception; >> >> >> >> =A0 =A0 /** >> >> - =A0 =A0 * Get the ordered certificate chain. >> >> + =A0 =A0 * Get the ordered certificate chain for a specific alias. >> >> =A0 =A0 =A0*/ >> >> - =A0 =A0public abstract X509Certificate[] getCertificateChain(); >> >> + =A0 =A0public abstract X509Certificate[] getCertificateChain(String >> alias); >> >> >> >> - =A0 =A0public abstract String getAlias(); >> >> + =A0 =A0public abstract int getAliasCount(); >> >> + >> >> + =A0 =A0public abstract String getAlias(int index); >> >> >> >> =A0 =A0 /** >> >> - =A0 =A0 * Return the private Key >> >> + =A0 =A0 * Return the private Key for a specific alias >> >> =A0 =A0 =A0*/ >> >> - =A0 =A0public abstract PrivateKey getPrivateKey(); >> >> + =A0 =A0public abstract PrivateKey getPrivateKey(String alias); >> >> >> >> =A0 =A0 public static final JmeterKeyStore getInstance(String type) t= hrows >> >> Exception { >> >> =A0 =A0 =A0 =A0 // JAVA 1.4 now handles all keystore types, so just u= se default >> >> >> >> Modified: jakarta/jmeter/trunk/xdocs/changes.xml >> >> URL: >> >> >> http://svn.apache.org/viewvc/jakarta/jmeter/trunk/xdocs/changes.xml?rev= =3D1187840&r1=3D1187839&r2=3D1187840&view=3Ddiff >> >> >> >> >> =3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D= =3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D= =3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D= =3D=3D=3D=3D >> >> --- jakarta/jmeter/trunk/xdocs/changes.xml (original) >> >> +++ jakarta/jmeter/trunk/xdocs/changes.xml Sun Oct 23 01:50:55 2011 >> >> @@ -137,6 +137,7 @@ Mirror server now uses default port 8081 >> >> =A0<h3>HTTP Samplers</h3> >> >> =A0<ul> >> >> =A0<li>Bug 51981 - Better support for file: protocol in HTTP sampler<= /li> >> >> +<li>Bug 52033 - Allowing multiple certificates (JKS)</li> >> >> =A0</ul> >> >> >> >> =A0<h3>Other samplers</h3> >> >> >> >> >> >> >> >> --------------------------------------------------------------------- >> >> To unsubscribe, e-mail: [email protected] >> >> For additional commands, e-mail: [email protected]= g >> >> >> >> >> > >> > >> > -- >> > Cordialement. >> > Philippe Mouawad. >> > >> >> --------------------------------------------------------------------- >> To unsubscribe, e-mail: [email protected] >> For additional commands, e-mail: [email protected] >> >> > > > -- > Cordialement. > Philippe Mouawad. >