0

I am trying to configure https in my apache camel Spring Boot REST application (using apache-camel v3.11.1, springboot v2.5.3) with keystore having multiple certificates.

Problem:

Application run failed

org.apache.camel.RuntimeCamelException: java.lang.IllegalStateException: KeyStores with multiple certificates are not supported on the base class org.eclipse.jetty.util.ssl.SslContextFactory. (Use org.eclipse.jetty.util.ssl.SslContextFactory$Server or org.eclipse.jetty.util.ssl.SslContextFactory$Client instead)
    at org.apache.camel.RuntimeCamelException.wrapRuntimeCamelException(RuntimeCamelException.java:51) ~[camel-api-3.11.1.jar:3.11.1]

Project setup:

pom.xml: (dependencies only, to show that I am not using spring-boot-web-starter)

    ..
    <dependencies>
        <dependency>
            <groupId>org.springframework.boot</groupId>
            <artifactId>spring-boot-starter</artifactId>
        </dependency>
        <dependency>
            <groupId>org.apache.camel.springboot</groupId>
            <artifactId>camel-spring-boot-starter</artifactId>
        </dependency>
        <dependency>
            <groupId>org.apache.camel.springboot</groupId>
            <artifactId>camel-jetty-starter</artifactId>
        </dependency>
        ..
        ..<!-- all other required dependencies are in place-->
        ..
    </dependencies>
    ..

application.properties

#camel.component.jetty.keystore=keystore-with-one-certificate.jks # WORKS
camel.component.jetty.keystore=keystore-with-multiple-certificates.jks # DOESN'T WORK
camel.component.jetty.ssl-key-password=password
camel.component.jetty.ssl-password=password

Rest Route:

        restConfiguration()
        .component("jetty")
        .scheme("https")
        .port("8080");
        
        rest()
        .path("/api")
        .get("/{name}")
         ..
         ..
        .to("direct:x");

Looked at answers in the below posts, but still not able to resolve the exception that I get,

  1. https://stackoverflow.com/a/60598953/6363894,
  2. https://stackoverflow.com/a/55499113/6363894

I know that exception clearly states to use org.eclipse.jetty.util.ssl.SslContextFactory$Server, but I don't understand how/where to use SslContextFactory.Server object.

SslContextFactory.Server sslContextFactory = new SslContextFactory.Server();
sslContextFactory.setKeyStoreResource(findKeyStorePath());
sslContextFactory.setKeyStorePassword("password");
sslContextFactory.setKeyManagerPassword("password");
sslContextFactory.setNeedClientAuth(true); 

Also I've created a bean for sslContextParameters and added that to restConfiguration as below, this time application runs successfully but then when I test, SSL handshake fails.

       restConfiguration()
        .component("jetty")
        .endpointProperty("sslContextParameters", "#sslContextParameters")
        .scheme("https")
        .port("8080");


@Bean(name = "sslContextParameters")
    public SSLContextParameters setSSLContextParameters() {
        
        KeyStoreParameters ksp = new KeyStoreParameters();
        ksp.setResource("keystore-with-multiple-certificates.jks");
        ksp.setPassword("password");

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

        SSLContextServerParameters scsp = new SSLContextServerParameters();
        scsp.setClientAuthentication("REQUIRE");
        
        SSLContextParameters scp = new SSLContextParameters();
        scp.setServerParameters(scsp);
        scp.setKeyManagers(kmp);
        
        return scp;
    }

Any help on how to configure SslContextFactory.Server object with the restConfigurations() or any other way I can achieve this? I'll update the post, if any more details are required.

Vijay Kumar
  • 186
  • 1
  • 9

0 Answers0