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

Reply via email to