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

Reply via email to