Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Added a (Key/Trust)StoreOptions configuration properties #2194

Merged
merged 1 commit into from
Oct 1, 2024
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
Original file line number Diff line number Diff line change
Expand Up @@ -4,14 +4,24 @@

import io.smallrye.graphql.client.impl.GraphQLClientConfiguration;
import io.smallrye.graphql.client.vertx.ssl.SSLTools;
import io.vertx.core.buffer.Buffer;
import io.vertx.core.http.HttpClientOptions;
import io.vertx.core.net.JksOptions;
import io.vertx.core.net.KeyCertOptions;
import io.vertx.core.net.ProxyOptions;
import io.vertx.core.net.SSLOptions;
import io.vertx.core.net.TrustOptions;

public class VertxClientOptionsHelper {

public static void applyConfigToVertxOptions(HttpClientOptions options, GraphQLClientConfiguration configuration) {
if (options.getTrustStoreOptions() == null && configuration.getTrustStore() != null) {
configure(options, configuration);
TrustOptions tlsTrustStoreOptions = (TrustOptions) configuration.getTlsTrustStoreOptions();
KeyCertOptions tlsKeyStoreOptions = (KeyCertOptions) configuration.getTlsKeyStoreOptions();
if (tlsTrustStoreOptions != null) {
options.setSsl(true);
options.setTrustOptions(tlsTrustStoreOptions);
} else if (options.getTrustStoreOptions() == null && configuration.getTrustStore() != null) { // deprecated in Quarkus
options.setSsl(true);
JksOptions trustStoreOptions = new JksOptions();
KeyStore trustStore = SSLTools.createKeyStore(configuration.getTrustStore(),
Expand All @@ -21,8 +31,10 @@ public static void applyConfigToVertxOptions(HttpClientOptions options, GraphQLC
trustStoreOptions.setPassword(new String(configuration.getTrustStorePassword()));
options.setTrustStoreOptions(trustStoreOptions);
}

if (options.getKeyStoreOptions() == null && configuration.getKeyStore() != null) {
if (tlsKeyStoreOptions != null) {
options.setSsl(true);
options.setKeyCertOptions(tlsKeyStoreOptions);
} else if (options.getKeyStoreOptions() == null && configuration.getKeyStore() != null) { // deprecated in Quarkus
options.setSsl(true);
JksOptions keyStoreOptions = new JksOptions();
KeyStore keyStore = SSLTools.createKeyStore(configuration.getKeyStore(),
Expand All @@ -45,10 +57,26 @@ public static void applyConfigToVertxOptions(HttpClientOptions options, GraphQLC
if (configuration.getMaxRedirects() != null) {
options.setMaxRedirects(configuration.getMaxRedirects());
}
}

if (options.isSsl()) {
// TODO: this is not supported yet
private static void configure(HttpClientOptions options, GraphQLClientConfiguration graphQLClientConfiguration) {
options.setForceSni(graphQLClientConfiguration.usesSni() != null && graphQLClientConfiguration.usesSni());
if (graphQLClientConfiguration.getHostnameVerificationAlgorithm() == null
|| graphQLClientConfiguration.getHostnameVerificationAlgorithm().equals("NONE")) {
options.setVerifyHost(false);
}
SSLOptions sslOptions = (SSLOptions) graphQLClientConfiguration.getSslOptions();
if (sslOptions != null) {
options.setSslHandshakeTimeout(sslOptions.getSslHandshakeTimeout());
options.setSslHandshakeTimeoutUnit(sslOptions.getSslHandshakeTimeoutUnit());
for (String suite : sslOptions.getEnabledCipherSuites()) {
options.addEnabledCipherSuite(suite);
}
for (Buffer buffer : sslOptions.getCrlValues()) {
options.addCrlValue(buffer);
}
options.setEnabledSecureTransportProtocols(sslOptions.getEnabledSecureTransportProtocols());
options.setUseAlpn(sslOptions.isUseAlpn());
}
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -34,7 +34,6 @@ public void serverAuthentication_correctTruststore() throws Exception {
System.setProperty("ts/mp-graphql/truststore", "classpath:ssl/client.pkcs12.truststore");
System.setProperty("ts/mp-graphql/truststorePassword", "clienttruststorepassword");
System.setProperty("ts/mp-graphql/truststoreType", "PKCS12");

try (MyClient client = TypesafeGraphQLClientBuilder.newBuilder()
.configKey("ts")
.endpoint("https://127.0.0.1:" + server.actualPort())
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -77,6 +77,33 @@ public class GraphQLClientConfiguration {
*/
private String keyStoreType;

/**
* The key store options, already contains key store.
*/
private Object tlsKeyStoreOptions;

/**
* The trust store options, already contains trust store.
*/
private Object tlsTrustStoreOptions;

/**
* SSL options for connection.
*/
private Object sslOptions;

/**
* Indicates whether Server Name Indication (SNI) is enabled for this connection.
* When SNI is enabled, the client sends the server name during the TLS handshake,
* allowing the server to select the appropriate certificate based on the hostname.
*/
private Boolean usesSni;

/**
* Specifies the algorithm used for hostname verification during the TLS handshake.
*/
private String hostnameVerificationAlgorithm;

/**
* Hostname of the proxy to use.
*/
Expand Down Expand Up @@ -273,6 +300,46 @@ public void setAllowUnexpectedResponseFields(Boolean allowUnexpectedResponseFiel
this.allowUnexpectedResponseFields = allowUnexpectedResponseFields;
}

public Object getTlsKeyStoreOptions() {
return tlsKeyStoreOptions;
}

public void setTlsKeyStoreOptions(Object tlsKeyStoreOptions) {
this.tlsKeyStoreOptions = tlsKeyStoreOptions;
}

public Object getTlsTrustStoreOptions() {
return tlsTrustStoreOptions;
}

public void setTlsTrustStoreOptions(Object tlsTrustStoreOptions) {
this.tlsTrustStoreOptions = tlsTrustStoreOptions;
}

public Boolean usesSni() {
return usesSni;
}

public void setUsesSni(Boolean usesSni) {
this.usesSni = usesSni;
}

public String getHostnameVerificationAlgorithm() {
return hostnameVerificationAlgorithm;
}

public void setHostnameVerificationAlgorithm(String hostnameVerificationAlgorithm) {
this.hostnameVerificationAlgorithm = hostnameVerificationAlgorithm;
}

public Object getSslOptions() {
return sslOptions;
}

public void setSslOptions(Object sslOptions) {
this.sslOptions = sslOptions;
}

/**
* Merge the `other` configuration into this one. Values in `other` take precedence.
* This method has to be idempotent because it can be called multiple times to allow for changes in configuration.
Expand Down Expand Up @@ -350,6 +417,21 @@ public GraphQLClientConfiguration merge(GraphQLClientConfiguration other) {
if (other.allowUnexpectedResponseFields != null) {
this.allowUnexpectedResponseFields = other.allowUnexpectedResponseFields;
}
if (other.tlsKeyStoreOptions != null) {
this.tlsKeyStoreOptions = other.tlsKeyStoreOptions;
}
if (other.tlsTrustStoreOptions != null) {
this.tlsTrustStoreOptions = other.tlsTrustStoreOptions;
}
if (other.usesSni != null) {
this.usesSni = other.usesSni;
}
if (other.hostnameVerificationAlgorithm != null) {
this.hostnameVerificationAlgorithm = other.hostnameVerificationAlgorithm;
}
if (other.sslOptions != null) {
this.sslOptions = other.sslOptions;
}
return this;
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -126,6 +126,10 @@ private GraphQLClientConfiguration readConfigurationByKey(String clientName) {
.ifPresent(configuration::setExecuteSingleOperationsOverWebsocket);
mpConfig.getOptionalValue(clientName + "/mp-graphql/allowUnexpectedResponseFields", Boolean.class)
.ifPresent(configuration::setAllowUnexpectedResponseFields);
mpConfig.getOptionalValue(clientName + "/mp-graphql/hostnameVerificationAlgorithm", String.class)
.ifPresent(configuration::setHostnameVerificationAlgorithm);
mpConfig.getOptionalValue(clientName + "/mp-graphql/usesSni", Boolean.class)
.ifPresent(configuration::setUsesSni);
return configuration;
}

Expand Down
Loading