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