Hi All,

I have an implementation of the Jetty component (Camel 3.7.3). Today I
struggled with it a bit. I have no issues anymore, but I thought maybe good
to share here anyway.

My camel app:

A Jetty component hosting an endpoint to get messages. The hosted url can
be set by the user (through a property)
I want them to choose between https and https.

For example:

jetty://http://0.0.0.0:8080/order/

or

jetty://https://0.0.0.0:8080/order/

My idea at first was to go for HTTPS by default.

1) Creating a keystore in the background (as in Jetty component
documentation).
2) Setting to use the keystore by Jetty globally like this:

((SSLContextParametersAware)
context.getComponent("jetty")).setUseGlobalSslContextParameters(true);

The idea was that HTTPS is the default, but when users want to use HTTP,
they can set it like this:

jetty://http://0.0.0.0:8080/order/?useGlobalSslContextParameters=false

But this didn't work. When using HTTP it says:

Error: Parse Error: Expected HTTP/

Basically it means that HTTPS is still expected. During implementation, I
noticed that:

1) The following parameters seems not to be available in the camel-catalog:
useGlobalSslContext, keystore, sslPassword, sslKeyPassword
2) The parameters don't seems to take effect when I use them.
3) The documentation speaks of "JettyComponent.class", but only
"JettyHttpComponent.class" seems available.
4) The documentation speaks of

KeyManagersParameters kmp = new KeyManagersParameters();

but as the .p12 file is for host shouldn't this be

TrustManagersParameters tmp = new TrustManagersParameters();

5) In "CamelInAction2 11.4 transport security " the keystore password and
key password are different. In JDK11 this leads to:

"org.apache.camel.RuntimeCamelException:
java.security.UnrecoverableKeyException: Get Key failed: Given final block
not properly padded. Such issues can arise if a bad key is used during
decryption." (See
https://stackoverflow.com/questions/15967650/caused-by-java-security-unrecoverablekeyexception-cannot-recover-key).
So I made both passwords the same.

At the end I implemented it the other way around by setting:

registry.bind("ssl", sslContextParameters);

Now HTTP can be used without options and the for the HTTPS the users needs
to set:

jetty://http://0.0.0.0:8080/order/?sslContextParameters=#ssl

So I don't have an issue anymore, but I am unsure why my first approach
didn't work.

On a more general note: Maybe the whole thing could be made developer
friendly, where for example you can write the following code:

context.useDefaultKeystore("path/to/keystore","password");
context.useDefaultTruststore("path/to/keystore","password");

Where in the background this is done:

KeyStoreParameters ksp = new KeyStoreParameters();
ksp.setResource("/users/home/server/keystore.jks");
ksp.setPassword("keystorePassword");

KeyManagersParameters kmp = new KeyManagersParameters();
kmp.setKeyStore(ksp);
kmp.setKeyPassword("keyPassword");

SSLContextServerParameters scsp = new SSLContextServerParameters();
scsp.setClientAuthentication(ClientAuthentication.REQUIRE);
SSLContextParameters scp = new SSLContextParameters();
scp.setServerParameters(scsp);
scp.setKeyManagers(kmp);

SSLContext context = scp.createSSLContext();
SSLEngine engine = scp.createSSLEngine();

//And then for all supported components of the
https://camel.apache.org/manual/latest/camel-configuration-utilities.html
((SSLContextParametersAware)
context.getComponent("sslSupportComponent")).setUseGlobalSslContextParameters(true);

This way you can easily set HTTPS support explicitly by default for the
complete context/all supported components. An option to not use SSL on an
URI could be like "useGlobalSSLContext=false". So there is still the option
to deviate from it, but it's secure by default.

Kind regards,

Raymond

Reply via email to