Hi Jerome,

Jerome Louvel wrote:
Hi Bruno,

[...]

1. I can't find which properties need to be used for setting the keystores and truststores used by the clients. Did I miss something? I've had to use -Djavax.net.ssl.keyStore, and similar VM parameters.

No those parameters are indeed missing :-/

OK. I'll try to address this.


2. As Chuck Hinson pointed out as part of Issue 281, keystore and truststore should be separate.

Could we add "truststore*" parameters? If they are not present, we could
fall back on current behavior, reusing matching "keystore*" parameters.

Yes, this seems sensible.
So, I think I'll keep keystore* for the server-side (for compatibility), add an optional trustore* for the server-side (falling back on the server keystore*), add an optional clientKeystore* for the client-side (falling back on keystore*), add an optional clientTruststore* (falling back on clientKeystore* and truststore*, I haven't really thought through which order would be best...)



3. The implementation that uses the keystore seem to rely on the fact that these keystores are always files (at least in the Jetty and Grizzly helpers, the Simple helper can handle a null keystorePath). However, this is not always true. Some keystores are not file-based: PKCS#11 tokens and the Apple KeychainStore.

OK. To be honest, I wasn't aware of this subtelety :)
Would it be hard to provide support for configuring these additional
keystore types?


One way consists of configuring the PKCS#11 provider in the java.security properties, which will add a new (named) provider. With a keystoreProvider property, it should then just be a matter of allowing either the InputStream or the provider name to be null, that is, changing statements like this:
      KeyStore keyStore = KeyStore.getInstance(getKeystoreType());
      FileInputStream fis = new FileInputStream(getKeystorePath());
      keyStore.load(fis, getKeystorePassword().toCharArray());

into something like this:
      String keystoreProvider = getKeystoreProvider();
      KeyStore keyStore;
      if (keystoreProvider == null)
          keyStore = KeyStore.getInstance(getKeystoreType());
      else
keyStore = KeyStore.getInstance(getKeystoreType(), keystoreProvider);
      FileInputStream fis = null;
      String keystorePath = getKeystorePath();
      if (keystorePath != null)
          fis = new FileInputStream(getKeystorePath());
      keyStore.load(fis, getKeystorePassword().toCharArray());

This would allow both existing keystore, PKCS#11 and Apple KeychainStore to be configurable from the same sort kind of properties. I'm not sure if all connectors would support this, but this seems reasonably easy to implement. In fact, that's more or less what the current Simple HttpsServerHelper does. Is there a guideline in Restlet regarding which coding style is better between "( ) ? : " and "if() {} else {}"?


The other way would be to configure the PKCS#11 provider dynamically, which would require a few more properties, more re-factoring, more special cases to handle...



I'd be interested in seeing these issues fixed, and I could have a go at it. The way I'm thinking of doing it would be to create more parameters: serverKeystorePath, serverKeystoreProvider, serverKeystoreType, serverKeystorePassword, serverKeyPassword, serverTruststorePath, serverTruststoreProvider, serverTruststoreType, serverTruststorePassword, serverCertAlgorithm + another set of these for client*.

Sure, that sounds good. Would be keep the current parameters in case we want
to use the same stores for both client and server certificates?

Yes, indeed. However, I've already run into other related problems for trying to use the same keystore for the client and the server.

If a keystore contains both a server and a client set of credentials (key+certificate), it seems that the server connectors don't necessarily pick up the right one. I made up a TestCA which signed a certificate with CN=localhost (for the server) and another with CN=testclient to be used by the client and bundled them in the same keystore. The server helpers (and what they rely one) were using 'testclient' as a server certificate. To be fair my test certificates don't have any usage constraints, so maybe the underlying servers would have looked through the keystores to find only suitable certificates, but I couldn't really find where to specify the name of the alias to be used. There might be a wider issue to look into regarding SSL connections: serving several certificates if multiple connectors on different IP addresses and multiple virtual hosts, certificate with alternate subject names, behaviour with TLS, ... This can become complex quite rapidly, and would probably take a long time to address (and would also very certainly affect Jetty and Grizzly).
In this context, separating client and server keystores seems easier :-)




Best regards,

Bruno.

Reply via email to