Re: HTTP2 with WebSockets

2019-02-06 Thread Jesse Schulman
I could add a second port but then I’d have to change how the load balancer
works to add even more magic there than I already have... not sure http2 is
worth that effort.
On Wed, Feb 6, 2019 at 6:54 PM John Larsen  wrote:

> I am interested in this too. Basically we've had to set another port in
> which the app can access tomcat for websockets directly. We've not been
> able to get this to work over httpd.
> John
>
>
> On Wed, Feb 6, 2019 at 5:32 PM Jesse Schulman 
> wrote:
>
> > Is it possible for tomcat to run with HTTP2 and WebSockets on the same
> > connector?  I have tried configuring it myself and looked for examples
> > without success.
> >
> > Thanks!
> > Jesse
> >
>


HTTP2 with WebSockets

2019-02-06 Thread Jesse Schulman
Is it possible for tomcat to run with HTTP2 and WebSockets on the same
connector?  I have tried configuring it myself and looked for examples
without success.

Thanks!
Jesse


SSL Session Cache with Tomcat 9 and Java 9

2018-05-16 Thread Jesse Schulman
I noticed on ssllabs.com that when I upgrade from java 8 to java 9 (9.0.4
to be exact) that without changing any other variables I start to get
"Session resumption (caching) No (IDs assigned but not accepted)" as a
warning.

I also tried explicitly setting the sessionCacheSize (even tho docs say
default is 0 which means unlimited size) and that did not help.

Anyone else seeing this or know how to get session cache working again on
java 9?

Thanks!
Jesse


Re: How to get the AbstractEndpoint from Tomcat with tomcat-embed

2017-12-08 Thread Jesse Schulman
Got it, that works and I was able to accomplish exactly what I needed,
thank you!

One side note, the name ended up being:
"Tomcat:name=\"https-jsse-nio-8443\",type=ThreadPool"

Which is a different order than your example so I am using the
ObjectName(String domain, Hashtable table) constructor so
that I don't depend on order.

I was a little concerned that the name value had quotes in the string while
the type value did not, meaning the name value has to be
"\"https-jsse-nio-8443\"" while the type is just "ThreadPool".  Is this
expected and should I keep an eye out for that possibly changing in a
future version?

Thanks again for your help!
Jesse


On Thu, Dec 7, 2017 at 5:43 AM Mark Thomas  wrote:

> On 06/12/17 18:32, Jesse Schulman wrote:
> > For some reason there are no Catalina names from that MBean server:
> >
> > Registry.getRegistry(null, null).getMBeanServer().getDomains()
> >
> > yields
> >
> > JMImplementation, java.util.logging, java.lang, Tomcat,
> com.sun.management,
> > null, java.nio
> >
> > and
> >
> > Registry.getRegistry(null, null).getMBeanServer().queryMBeans(new
> > ObjectName("Catalina:*"), null)
> >
> > yields an empty set
> >
> > Maybe there is something I need to do to enable JMX for the Catalina
> > domain?  I didn't do anything to enable it for Tomcat but that domain
> seems
> > to show up already.
>
> The engine name is used as the MBean domain. For embedded, the engine
> name is "Tomcat" rather than "Catalina" so you'll want modify the MBean
> appropriately.
>
> > Also, if I can get access to the Endpoint MBean will I be able to get
> > access to the Endpoint instance to call those two new public methods to
> > pass my SSLHostConfig to the add method?
>
> No. You call the operations on the MBean and it takes care of the rest.
>
> Mark
>
>
> >
> > Thanks!
> > Jesse
> >
> >
> > On Wed, Dec 6, 2017 at 1:41 AM Mark Thomas  wrote:
> >
> >> On 06/12/17 00:17, Jesse Schulman wrote:
> >>> Now that 8.5.24 is released with new support for runtime
> >> SNI/SSLHostConfig
> >>> changes (thank you Mark!) I am trying to access the AbstractEndpoint
> from
> >>> our application to call these 2 new methods:
> >>>
> >>> public void addSslHostConfig(SSLHostConfig sslHostConfig, boolean
> >>> replace)
> >>>
> >>> public SSLHostConfig removeSslHostConfig(String hostName)
> >>>
> >>> We have an instance of the Tomcat class from which we can do
> >>> getConnector(), and that Connector can provide us with the
> >>> ProtocolHandler.  With ProtocolHandler we could safely cast to
> >>> AbstractProtocol but from there the getEndpoint method is protected.
> >>>
> >>> Is there a supported way to access the AbstractEndpoint via public
> >> methods
> >>> if I only have the Tomcat/Connector instances available?
> >>>
> >>> Or maybe this is possible to do with JMX?  If so I would need access to
> >> the
> >>> AbstractEndpoint directly so I can pass it my SSLHostConfig objects.
> >>
> >> The MBean for an Endpoint has a name that looks like this:
> >>
> >> Catalina:type=ThreadPool,name="http-nio-8080"
> >>
> >> The name part is the same as that shown in the logs. So if you see this:
> >>
> >> 06-Dec-2017 09:39:36.986 INFO [main]
> >> org.apache.coyote.AbstractProtocol.start Starting ProtocolHandler
> >> ["https-jsse-nio-8443"]
> >>
> >> then the MBean name will be:
> >>
> >> Catalina:type=ThreadPool,name="https-jsse-nio-8443"
> >>
> >> The MBean server should be obtainable with:
> >> Registry.getRegistry(null, null).getMBeanServer();
> >>
> >> Mark
> >>
> >> -
> >> To unsubscribe, e-mail: users-unsubscr...@tomcat.apache.org
> >> For additional commands, e-mail: users-h...@tomcat.apache.org
> >>
> >>
> >
>
>
> -
> To unsubscribe, e-mail: users-unsubscr...@tomcat.apache.org
> For additional commands, e-mail: users-h...@tomcat.apache.org
>
>


Re: How to get the AbstractEndpoint from Tomcat with tomcat-embed

2017-12-06 Thread Jesse Schulman
For some reason there are no Catalina names from that MBean server:

Registry.getRegistry(null, null).getMBeanServer().getDomains()

yields

JMImplementation, java.util.logging, java.lang, Tomcat, com.sun.management,
null, java.nio

and

Registry.getRegistry(null, null).getMBeanServer().queryMBeans(new
ObjectName("Catalina:*"), null)

yields an empty set

Maybe there is something I need to do to enable JMX for the Catalina
domain?  I didn't do anything to enable it for Tomcat but that domain seems
to show up already.

Also, if I can get access to the Endpoint MBean will I be able to get
access to the Endpoint instance to call those two new public methods to
pass my SSLHostConfig to the add method?

Thanks!
Jesse


On Wed, Dec 6, 2017 at 1:41 AM Mark Thomas  wrote:

> On 06/12/17 00:17, Jesse Schulman wrote:
> > Now that 8.5.24 is released with new support for runtime
> SNI/SSLHostConfig
> > changes (thank you Mark!) I am trying to access the AbstractEndpoint from
> > our application to call these 2 new methods:
> >
> > public void addSslHostConfig(SSLHostConfig sslHostConfig, boolean
> > replace)
> >
> > public SSLHostConfig removeSslHostConfig(String hostName)
> >
> > We have an instance of the Tomcat class from which we can do
> > getConnector(), and that Connector can provide us with the
> > ProtocolHandler.  With ProtocolHandler we could safely cast to
> > AbstractProtocol but from there the getEndpoint method is protected.
> >
> > Is there a supported way to access the AbstractEndpoint via public
> methods
> > if I only have the Tomcat/Connector instances available?
> >
> > Or maybe this is possible to do with JMX?  If so I would need access to
> the
> > AbstractEndpoint directly so I can pass it my SSLHostConfig objects.
>
> The MBean for an Endpoint has a name that looks like this:
>
> Catalina:type=ThreadPool,name="http-nio-8080"
>
> The name part is the same as that shown in the logs. So if you see this:
>
> 06-Dec-2017 09:39:36.986 INFO [main]
> org.apache.coyote.AbstractProtocol.start Starting ProtocolHandler
> ["https-jsse-nio-8443"]
>
> then the MBean name will be:
>
> Catalina:type=ThreadPool,name="https-jsse-nio-8443"
>
> The MBean server should be obtainable with:
> Registry.getRegistry(null, null).getMBeanServer();
>
> Mark
>
> -
> To unsubscribe, e-mail: users-unsubscr...@tomcat.apache.org
> For additional commands, e-mail: users-h...@tomcat.apache.org
>
>


How to get the AbstractEndpoint from Tomcat with tomcat-embed

2017-12-05 Thread Jesse Schulman
Now that 8.5.24 is released with new support for runtime SNI/SSLHostConfig
changes (thank you Mark!) I am trying to access the AbstractEndpoint from
our application to call these 2 new methods:

public void addSslHostConfig(SSLHostConfig sslHostConfig, boolean
replace)

public SSLHostConfig removeSslHostConfig(String hostName)

We have an instance of the Tomcat class from which we can do
getConnector(), and that Connector can provide us with the
ProtocolHandler.  With ProtocolHandler we could safely cast to
AbstractProtocol but from there the getEndpoint method is protected.

Is there a supported way to access the AbstractEndpoint via public methods
if I only have the Tomcat/Connector instances available?

Or maybe this is possible to do with JMX?  If so I would need access to the
AbstractEndpoint directly so I can pass it my SSLHostConfig objects.

Thanks!
Jesse


Re: Upgrading to 8.5.20 - issue when certificateKeyAlias is not set

2017-08-22 Thread Jesse Schulman
Will do, thanks Mark!

On Tue, Aug 22, 2017 at 8:42 AM Mark Thomas  wrote:

> On 21/08/17 22:54, Jesse Schulman wrote:
> > I'm pretty sure this is a bug/regression related to a recent change by
> > markt: http://svn.apache.org/viewvc?view=revision&revision=1800868
> >
> > I think the issue was there before but we weren't hitting it, because the
> > logic of taking the first alias from the keystore (even if it does not
> > alias a key) was already there, but only after this change did we start
> to
> > hit that code.
> >
> > We have worked around the issue with a "getFirstKeyAlias" method that we
> > use to set the certificateKeyAlias in our SSLHostConfigCertificate:
> >
> >private String getFirstKeyAlias(KeyStore keyStore) {
> >   try {
> >  Enumeration aliases = keyStore.aliases();
> >  while(aliases.hasMoreElements()) {
> > String alias = aliases.nextElement();
> > if (keyStore.isKeyEntry(alias))
> >return alias;
> > }
> >   } catch (KeyStoreException e) {
> >   LOGGER.error("Failed to find first key alias in keystore", e);
> >   }
> >
> >   return null;
> >}
> >
> > I think that something like this should around line 219 of JSSEUtil,
> where
> > currently it looks like this:
> >
> > Enumeration aliases = ks.aliases();
> > if (!aliases.hasMoreElements()) {
> > throw new IOException(sm.getString("jsse.noKeys"));
> > }
> >     keyAlias = aliases.nextElement();
> >
> >
> > Should I send this to the dev list instead?
>
> If you could create a Bugzilla issue for it, that would be great.
>
> Thanks,
>
> Mark
>
>
> >
> > Thanks!
> > Jesse
> >
> > On Wed, Aug 16, 2017 at 3:02 PM Jesse Schulman 
> wrote:
> >
> >> We use tomcat-embed and we have a test that is breaking with an upgrade
> >> from 8.5.12 to 8.5.20, it seems due to the fact that we do not set the
> >> certificateKeyAlias when we configure an SSLHostConfigCertificate.
> >>
> >> The documentation for certificateKeyAlias states "If not specified, the
> >> first *key* read from the keystore will be used."
> >>
> >> It seems that the first alias is being used and there is no check that
> it
> >> references a key.
> >>
> >> The result is that in JSSEUtil.getKeyManagers there is a call to
> >> KeyStore.getKey(keyAlias, keyPassArray) where keyAlias is actually an
> alias
> >> for a certificate, which leads to inMemoryKeyStore.setKeyEntry being
> passed
> >> null for the Key argument and eventually a KeyStoreException("Cannot
> store
> >> non-PrivateKeys").
> >>
> >> This worked previously with certificatekeyAlias being null.  I can
> confirm
> >> that this works just fine if I set that with the alias used when
> creating
> >> the KeyStore but I would rather not pass that alias around our code
> when I
> >> did not previously need to.
> >>
> >> Thanks!
> >> Jesse
> >>
> >>
> >>
> >
>
>
> -
> To unsubscribe, e-mail: users-unsubscr...@tomcat.apache.org
> For additional commands, e-mail: users-h...@tomcat.apache.org
>
>


Re: Upgrading to 8.5.20 - issue when certificateKeyAlias is not set

2017-08-21 Thread Jesse Schulman
I'm pretty sure this is a bug/regression related to a recent change by
markt: http://svn.apache.org/viewvc?view=revision&revision=1800868

I think the issue was there before but we weren't hitting it, because the
logic of taking the first alias from the keystore (even if it does not
alias a key) was already there, but only after this change did we start to
hit that code.

We have worked around the issue with a "getFirstKeyAlias" method that we
use to set the certificateKeyAlias in our SSLHostConfigCertificate:

   private String getFirstKeyAlias(KeyStore keyStore) {
  try {
 Enumeration aliases = keyStore.aliases();
 while(aliases.hasMoreElements()) {
String alias = aliases.nextElement();
if (keyStore.isKeyEntry(alias))
   return alias;
}
  } catch (KeyStoreException e) {
  LOGGER.error("Failed to find first key alias in keystore", e);
  }

  return null;
   }

I think that something like this should around line 219 of JSSEUtil, where
currently it looks like this:

Enumeration aliases = ks.aliases();
if (!aliases.hasMoreElements()) {
throw new IOException(sm.getString("jsse.noKeys"));
}
keyAlias = aliases.nextElement();


Should I send this to the dev list instead?

Thanks!
Jesse

On Wed, Aug 16, 2017 at 3:02 PM Jesse Schulman  wrote:

> We use tomcat-embed and we have a test that is breaking with an upgrade
> from 8.5.12 to 8.5.20, it seems due to the fact that we do not set the
> certificateKeyAlias when we configure an SSLHostConfigCertificate.
>
> The documentation for certificateKeyAlias states "If not specified, the
> first *key* read from the keystore will be used."
>
> It seems that the first alias is being used and there is no check that it
> references a key.
>
> The result is that in JSSEUtil.getKeyManagers there is a call to
> KeyStore.getKey(keyAlias, keyPassArray) where keyAlias is actually an alias
> for a certificate, which leads to inMemoryKeyStore.setKeyEntry being passed
> null for the Key argument and eventually a KeyStoreException("Cannot store
> non-PrivateKeys").
>
> This worked previously with certificatekeyAlias being null.  I can confirm
> that this works just fine if I set that with the alias used when creating
> the KeyStore but I would rather not pass that alias around our code when I
> did not previously need to.
>
> Thanks!
> Jesse
>
>
>


Upgrading to 8.5.20 - issue when certificateKeyAlias is not set

2017-08-16 Thread Jesse Schulman
We use tomcat-embed and we have a test that is breaking with an upgrade
from 8.5.12 to 8.5.20, it seems due to the fact that we do not set the
certificateKeyAlias when we configure an SSLHostConfigCertificate.

The documentation for certificateKeyAlias states "If not specified, the
first *key* read from the keystore will be used."

It seems that the first alias is being used and there is no check that it
references a key.

The result is that in JSSEUtil.getKeyManagers there is a call to
KeyStore.getKey(keyAlias, keyPassArray) where keyAlias is actually an alias
for a certificate, which leads to inMemoryKeyStore.setKeyEntry being passed
null for the Key argument and eventually a KeyStoreException("Cannot store
non-PrivateKeys").

This worked previously with certificatekeyAlias being null.  I can confirm
that this works just fine if I set that with the alias used when creating
the KeyStore but I would rather not pass that alias around our code when I
did not previously need to.

Thanks!
Jesse


Re: tomcat-embed 8.5.9 - runtime changes to SSLHostConfig objects

2017-01-09 Thread Jesse Schulman
On Mon, Jan 9, 2017 at 1:53 PM Mark Thomas  wrote:

> On 09/01/2017 20:13, Jesse Schulman wrote:
> > On Thu, Jan 5, 2017 at 9:48 PM Jesse Schulman 
> wrote:
> >
> >> On Thu, Jan 5, 2017 at 2:08 PM Mark Thomas  wrote:
> >>
> >> On 05/01/2017 21:05, Jesse Schulman wrote:
> >>> We are using tomcat-embed 8.5.9, java8 and running on Centos7.  Given
> >>> Tomcat's new support for SNI, we wish to support
> adding/removing/updating
> >>> certificates via our application at runtime without restarting tomcat
> or
> >>> binding/unbinding the port.
> >>>
> >>> Our configuration is very simple, we have a single servlet for all
> >>> requests, so we have a single connector/endpoint to manage all
> >>> SSLHostConfigs.
> >>>
> >>> It appears that by manipulating the list of SSLHostConfig objects in
> the
> >>> AbstractEndpoint we can achieve what we want, there however don't
> appear
> >> to
> >>> be any public methods available that allow that kind of operation.
> >>
> >> It should be possible with the current API. What can't you do?
> >>
> >>
> >> I don't think I can modify an existing/added SSLHostConfig (remove an
> old
> >> expiring certificate and add a new certificate).  I also don't think I
> can
> >> remove the SSLHostConfig for a given SNI hostname once it has been
> added.
> >>
> >>> I was able to extend a few tomcat classes (Connector,
> >>> AbstractHttp11JsseProtocol, NioEndpoint) to expose what I need and
> verify
> >>> that I can change the SSLHostConfig at runtime, however I would prefer
> to
> >>> use APIs fully supported by tomcat.
> >>>
> >>> Is there any way to do what I want with the currently available APIs,
> or
> >>> are there any plans to expose this kind of functionality?
> >>
> >> It depends exactly what you want to do.
> >>
> >> AbstractEndpoint.addSslHostConfig()
> >> AbstractEndpoint.findSslHostConfigs()
> >>
> >> should be enough.
> >>
> >>
> >> It seems addSslHostConfig does a putIfAbsent, which means I can't
> replace
> >> an existing SSLHostConfig to update the certificate for an SNI hostname
> (or
> >> the default SSLHostConfig).  I also can't remove an SSLHostConfig
> entirely,
> >> which is something we'd like to support in our application.  For me it
> >> would be simplest to create a new SSLHostConfig and replace the old one
> >> when there is a need to update a certificate.
> >>
> >>
> >>
> >>> If not, are there any risks or issues with taking the approach
> described
> >>> above by extending classes to expose what I need?
> >>
> >> It depends what you want to do. Generally, there is a risk we'll change
> >> an API you are depending on since a lot of those are treated as internal
> >> APIs. Some sample code might help.
> >>
> >>
> >> I would of course test when we upgrade tomcat, and leverage any new APIs
> >> that would allow me to remove any of my custom code.
> >>
> >> I extended AbstractHttp11JsseProtocol just so I could control which
> >> endpoint implementation was used and so I could get access to my
> endpoint
> >> implementation.  My protocol is basically a copy of Http11NioProtocol
> that
> >> constructs my endpoint implementation and has a getter for the same.
> >>
> >> The endpoint is where I added functionality and looks like this:
> >>
> >> public class MyNioEndpoint extends NioEndpoint {
> >> private static final MyLogger LOGGER =
> >> MyLogger.getLogger(MyNioEndpoint.class.getName());
> >>
> >> public void removeSSLHostConfig(String sniHostName) {
> >> if (Strings.isNullOrEmpty(sniHostName)) {
> >> LOGGER.error("Cannot remove host config for invalid
> hostname:
> >> " + sniHostName);
> >> return;
> >> }
> >>
> >> if (sniHostName.equals(getDefaultSSLHostConfigName())) {
> >> LOGGER.error("Cannot remove default SSLHostConfig");
> >> return;
> >> }
> >>
> >> SSLHostConfig removed = sslHostConfigs.remove(sniHostName);
> >> if (removed != null)
> >> releaseSSLContext(removed);
> >> }

Re: tomcat-embed 8.5.9 - runtime changes to SSLHostConfig objects

2017-01-09 Thread Jesse Schulman
On Thu, Jan 5, 2017 at 9:48 PM Jesse Schulman  wrote:

> On Thu, Jan 5, 2017 at 2:08 PM Mark Thomas  wrote:
>
> On 05/01/2017 21:05, Jesse Schulman wrote:
> > We are using tomcat-embed 8.5.9, java8 and running on Centos7.  Given
> > Tomcat's new support for SNI, we wish to support adding/removing/updating
> > certificates via our application at runtime without restarting tomcat or
> > binding/unbinding the port.
> >
> > Our configuration is very simple, we have a single servlet for all
> > requests, so we have a single connector/endpoint to manage all
> > SSLHostConfigs.
> >
> > It appears that by manipulating the list of SSLHostConfig objects in the
> > AbstractEndpoint we can achieve what we want, there however don't appear
> to
> > be any public methods available that allow that kind of operation.
>
> It should be possible with the current API. What can't you do?
>
>
> I don't think I can modify an existing/added SSLHostConfig (remove an old
> expiring certificate and add a new certificate).  I also don't think I can
> remove the SSLHostConfig for a given SNI hostname once it has been added.
>
> > I was able to extend a few tomcat classes (Connector,
> > AbstractHttp11JsseProtocol, NioEndpoint) to expose what I need and verify
> > that I can change the SSLHostConfig at runtime, however I would prefer to
> > use APIs fully supported by tomcat.
> >
> > Is there any way to do what I want with the currently available APIs, or
> > are there any plans to expose this kind of functionality?
>
> It depends exactly what you want to do.
>
> AbstractEndpoint.addSslHostConfig()
> AbstractEndpoint.findSslHostConfigs()
>
> should be enough.
>
>
> It seems addSslHostConfig does a putIfAbsent, which means I can't replace
> an existing SSLHostConfig to update the certificate for an SNI hostname (or
> the default SSLHostConfig).  I also can't remove an SSLHostConfig entirely,
> which is something we'd like to support in our application.  For me it
> would be simplest to create a new SSLHostConfig and replace the old one
> when there is a need to update a certificate.
>
>
>
> > If not, are there any risks or issues with taking the approach described
> > above by extending classes to expose what I need?
>
> It depends what you want to do. Generally, there is a risk we'll change
> an API you are depending on since a lot of those are treated as internal
> APIs. Some sample code might help.
>
>
> I would of course test when we upgrade tomcat, and leverage any new APIs
> that would allow me to remove any of my custom code.
>
> I extended AbstractHttp11JsseProtocol just so I could control which
> endpoint implementation was used and so I could get access to my endpoint
> implementation.  My protocol is basically a copy of Http11NioProtocol that
> constructs my endpoint implementation and has a getter for the same.
>
> The endpoint is where I added functionality and looks like this:
>
> public class MyNioEndpoint extends NioEndpoint {
> private static final MyLogger LOGGER =
> MyLogger.getLogger(MyNioEndpoint.class.getName());
>
> public void removeSSLHostConfig(String sniHostName) {
> if (Strings.isNullOrEmpty(sniHostName)) {
> LOGGER.error("Cannot remove host config for invalid hostname:
> " + sniHostName);
> return;
> }
>
> if (sniHostName.equals(getDefaultSSLHostConfigName())) {
> LOGGER.error("Cannot remove default SSLHostConfig");
> return;
> }
>
> SSLHostConfig removed = sslHostConfigs.remove(sniHostName);
> if (removed != null)
> releaseSSLContext(removed);
> }
>
> public void addOrUpdateSSLHostConfig(SSLHostConfig config) {
> if (config == null) {
> LOGGER.error("null SSLHostConfig provided");
> return;
> }
>
> String hostName = config.getHostName();
> if (Strings.isNullOrEmpty(hostName)) {
> LOGGER.error("Invalid SSLHostConfig provided, cannot
> add/update, hostname was empty");
> return;
> }
>
> for (SSLHostConfig loadedConfig : findSslHostConfigs()) {
> if (hostName.equals(loadedConfig.getHostName())) {
> sslHostConfigs.remove(hostName);
> releaseSSLContext(loadedConfig);
> addSslHostConfig(loadedConfig);
> return;
> }
> }
>
> addSslHostConfig(config);
> }
>
> }
>
> Thanks for the reply, your help/sugges

Re: tomcat-embed 8.5.9 - runtime changes to SSLHostConfig objects

2017-01-05 Thread Jesse Schulman
On Thu, Jan 5, 2017 at 2:08 PM Mark Thomas  wrote:

> On 05/01/2017 21:05, Jesse Schulman wrote:
> > We are using tomcat-embed 8.5.9, java8 and running on Centos7.  Given
> > Tomcat's new support for SNI, we wish to support adding/removing/updating
> > certificates via our application at runtime without restarting tomcat or
> > binding/unbinding the port.
> >
> > Our configuration is very simple, we have a single servlet for all
> > requests, so we have a single connector/endpoint to manage all
> > SSLHostConfigs.
> >
> > It appears that by manipulating the list of SSLHostConfig objects in the
> > AbstractEndpoint we can achieve what we want, there however don't appear
> to
> > be any public methods available that allow that kind of operation.
>
> It should be possible with the current API. What can't you do?
>
>
I don't think I can modify an existing/added SSLHostConfig (remove an old
expiring certificate and add a new certificate).  I also don't think I can
remove the SSLHostConfig for a given SNI hostname once it has been added.

> I was able to extend a few tomcat classes (Connector,
> > AbstractHttp11JsseProtocol, NioEndpoint) to expose what I need and verify
> > that I can change the SSLHostConfig at runtime, however I would prefer to
> > use APIs fully supported by tomcat.
> >
> > Is there any way to do what I want with the currently available APIs, or
> > are there any plans to expose this kind of functionality?
>
> It depends exactly what you want to do.
>
> AbstractEndpoint.addSslHostConfig()
> AbstractEndpoint.findSslHostConfigs()
>
> should be enough.
>

It seems addSslHostConfig does a putIfAbsent, which means I can't replace
an existing SSLHostConfig to update the certificate for an SNI hostname (or
the default SSLHostConfig).  I also can't remove an SSLHostConfig entirely,
which is something we'd like to support in our application.  For me it
would be simplest to create a new SSLHostConfig and replace the old one
when there is a need to update a certificate.


>
> > If not, are there any risks or issues with taking the approach described
> > above by extending classes to expose what I need?
>
> It depends what you want to do. Generally, there is a risk we'll change
> an API you are depending on since a lot of those are treated as internal
> APIs. Some sample code might help.
>

I would of course test when we upgrade tomcat, and leverage any new APIs
that would allow me to remove any of my custom code.

I extended AbstractHttp11JsseProtocol just so I could control which
endpoint implementation was used and so I could get access to my endpoint
implementation.  My protocol is basically a copy of Http11NioProtocol that
constructs my endpoint implementation and has a getter for the same.

The endpoint is where I added functionality and looks like this:

public class MyNioEndpoint extends NioEndpoint {
private static final MyLogger LOGGER =
MyLogger.getLogger(MyNioEndpoint.class.getName());

public void removeSSLHostConfig(String sniHostName) {
if (Strings.isNullOrEmpty(sniHostName)) {
LOGGER.error("Cannot remove host config for invalid hostname: "
+ sniHostName);
return;
}

if (sniHostName.equals(getDefaultSSLHostConfigName())) {
LOGGER.error("Cannot remove default SSLHostConfig");
return;
}

SSLHostConfig removed = sslHostConfigs.remove(sniHostName);
if (removed != null)
releaseSSLContext(removed);
}

public void addOrUpdateSSLHostConfig(SSLHostConfig config) {
if (config == null) {
LOGGER.error("null SSLHostConfig provided");
return;
}

String hostName = config.getHostName();
if (Strings.isNullOrEmpty(hostName)) {
LOGGER.error("Invalid SSLHostConfig provided, cannot
add/update, hostname was empty");
return;
}

for (SSLHostConfig loadedConfig : findSslHostConfigs()) {
if (hostName.equals(loadedConfig.getHostName())) {
sslHostConfigs.remove(hostName);
releaseSSLContext(loadedConfig);
addSslHostConfig(loadedConfig);
return;
}
}

addSslHostConfig(config);
}

}

Thanks for the reply, your help/suggestions are much appreciated!
Jesse


>
> Mark
>
> -
> To unsubscribe, e-mail: users-unsubscr...@tomcat.apache.org
> For additional commands, e-mail: users-h...@tomcat.apache.org
>
>


tomcat-embed 8.5.9 - runtime changes to SSLHostConfig objects

2017-01-05 Thread Jesse Schulman
We are using tomcat-embed 8.5.9, java8 and running on Centos7.  Given
Tomcat's new support for SNI, we wish to support adding/removing/updating
certificates via our application at runtime without restarting tomcat or
binding/unbinding the port.

Our configuration is very simple, we have a single servlet for all
requests, so we have a single connector/endpoint to manage all
SSLHostConfigs.

It appears that by manipulating the list of SSLHostConfig objects in the
AbstractEndpoint we can achieve what we want, there however don't appear to
be any public methods available that allow that kind of operation.

I was able to extend a few tomcat classes (Connector,
AbstractHttp11JsseProtocol, NioEndpoint) to expose what I need and verify
that I can change the SSLHostConfig at runtime, however I would prefer to
use APIs fully supported by tomcat.

Is there any way to do what I want with the currently available APIs, or
are there any plans to expose this kind of functionality?

If not, are there any risks or issues with taking the approach described
above by extending classes to expose what I need?

Thanks!
Jesse