"Bill Barker" <[EMAIL PROTECTED]> wrote in message news:[EMAIL PROTECTED] > > Pretty much a pipe-dream, since the SSL protocol requires that the server > send it's cert before it even knows the Host, much less the webapp :). > There is pretty much no other place it can go other than with the > Connector. It works.
> Not strictly true, but practically no browser supports the protocol > extension that allows this, so it's currently not worth the effort of > trying to support it. It should has nothing to do with browsers. Furthermore, I have report a bug on January 20, 2006. The KeyManager does not always return "tomcat". The bug is here: In the getKeyManagers of org.apache.tomcat.util.net.jsse.JSSE14SocketFactory kms = kmf.getKeyManagers(); jacklog("return "+kms.length+" KeyManagers."); if (keyAlias != null) { if (JSSESocketFactory.defaultKeystoreType.equals(keystoreType)) { keyAlias = keyAlias.toLowerCase(); } for(int i=0; i<kms.length; i++) { kms[i] = new JSSEKeyManager((X509KeyManager)kms[i], keyAlias); } } return kms; When the keyAlias==null, we don't use our own JSSEKeyManager at all. If I change it to the following: kms = kmf.getKeyManagers(); jacklog("return "+kms.length+" KeyManagers."); if (keyAlias != null) { if (JSSESocketFactory.defaultKeystoreType.equals(keystoreType)) { keyAlias = keyAlias.toLowerCase(); } } for(int i=0; i<kms.length; i++) { kms[i] = new JSSEKeyManager((X509KeyManager)kms[i], "whatever doesn't matter since we will choose later."); } return kms; And change the chooseServerAlias in JSSEKeyManager public String chooseServerAlias(String keyType, Principal[] issuers, Socket socket) { System.out.println("in chooseServerAliases with key type:"+keyType); if(issuers!=null) { System.out.println("\tissuers:"+issuers.length); for(int i=0;i<issuers.length;i++) { System.out.print("\t"); System.out.println(issuers[i].toString()); } } if(socket!=null) { System.out.println("\tsocket::"+socket.toString()); } String delegateReturn=delegate.chooseServerAlias(keyType,issuers,socket); System.out.println("\tdelegate return:"+delegateReturn); String[] as=new String[2]; as[0]="tomcat"; as[1]="itsnows"; System.out.println("\tplease choose 0:"+as[0]+" 1:"+as[1]); //JSSESocketFactory.pause(); int c=0; giveup: while(c!=0x30&&c!=0x31) { try { c=System.in.read(); } catch(Exception e) { System.out.println("\tException:"+e.getMessage()); JSSESocketFactory.pause(); c=0x30; break giveup; } } //return serverKeyAlias; return as[c-0x30]; } I will have the opportunity to select a server certificate ("tomcat" or "itsnows") to send out. Now, it is clear that whenever javax.net.ssl needs a server certificate, it will call our KeyManager (JSSEKeyManager). If we know who is using the SSL at the moment, we know which certificate we should send out. In tomcat, we have only two types of SSL users: the engine or a web-app. If we redirect a connection to the SSL connector, we know which web-app is using the SSL, we should send the certificate of the web-app. If it doesn't have a certificate and it is configured to use the certificate of its virtual host, use the certificate of its virtual host. When a web user initiates an SSL connection, since we don't know which web-app the user wants to access, we can send the engine certificate. If it is too much work or too costly to use security manager, we can just use a ThreadLocal object to record the user. Such an object can be put in our KeyManager (JSSEKeyManager) or other places. I suggest to keep it with the UserManager and we can use it for many other purpose. I don't think we need a stack to store the callers (the engine & web-apps). In UserManager, I wrote this (Can be put in JSSEKeyManager, too): public static ThreadLocal tlCaller=new ThreadLocal(); private static Context engine;//the engine context //when we know the SSL is going to be used by a specific web-app, or the thread is going to run on a specific web-app public void attach(Context caller) { tlCaller.set(caller); } //When we know the SSL is no longer to be used by the specific web-app, //or the thread is going to stop running on the specific a web-app public void deattach() { tlCaller.set(engine); } //when catalina starts, this should be called by the engine. public void set(Context engine) { this.engine=engine; } The Caller (Context) should implement: String getCertificateAlias();//since getName has been used in other meaning, and getAlias doesn't carry enough info. Then in JSSEKeyManager, we implement public String chooseServerAlias(String keyType, Principal[] issuers, Socket socket) { return UserManager.tlCaller.getCertificateAlias(); } Hi, guys, I believe that it can be done in this way. Do you know where we can call UserManager.set(engine); //we have only one engine, it will not be too difficult to find a good place. UserManager.attach(context); //The container of a web-app. UserManager.deattach(); Furthermore, once we know which web-app the user wants to access, we could/should close the SSL connection using the engine certificate, and initiate a new SSL connection using the certificate of the web-app. You might think that it is too costly for this. That will be another little thing. Any opinion, please just reply or send me a message. [EMAIL PROTECTED] Thanks. --------------------------------------------------------------------- To unsubscribe, e-mail: [EMAIL PROTECTED] For additional commands, e-mail: [EMAIL PROTECTED]