"Jack" <[EMAIL PROTECTED]> wrote in message news:[EMAIL PROTECTED] > > "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. >
I don't know about you, but I've got way better uses for my time than to sit at a terminal selecting certs to send ;-). > 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. > No we don't. It's a new connection from Tomcat's point of view, totally indisigushable from any other new connection. > > > 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. > Yeah, well, that's the rub. In a normal SSL connection, the server-cert is only ever sent when the client initiates a SSL connection. > > > 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 Tomcat (esp. with the HTTP/1.1 Connector), Threads are very long-lived objects, and are reused for very many unrelated connections. This makes ThreadLocal a pretty dangerous thing to use unless you are simply using within one Request lifecycle. > > 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 > This would be in your digester rules (which would necessarily change to recognize your new tag). > 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. > Closing it would be pretty much fatal ;-). However, it is possible to renegotiate the connection. Since you seem to be interested in the codebase, look at how JSSESupport.getPeerCertificateChain(true) does it (yes, I know it's for client-certs, but the same thing could be done to change the server-cert). And, yes, it's expensive. Also, I don't know (since I've never tried :) how many browsers would freak out getting a different server-cert on a renegotiate. The new server-cert Subject-DN has to be the same (the DNS name of the server), or the client will reject it. I suppose you could change the signer (as long as the client still trusts it), or, say the Subject-OU. Of course, there are much easier ways to pass information to the client than through the server-cert :). > > > 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]