"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]