Skip to content

Commit

Permalink
WIP
Browse files Browse the repository at this point in the history
  • Loading branch information
cescoffier committed Jun 6, 2024
1 parent 75928a5 commit f81ef4f
Show file tree
Hide file tree
Showing 2 changed files with 93 additions and 20 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -10,6 +10,7 @@
import java.net.URI;
import java.util.ArrayList;
import java.util.List;
import java.util.Optional;
import java.util.Set;

import io.quarkus.arc.Arc;
Expand All @@ -22,10 +23,14 @@
import io.quarkus.redis.runtime.client.config.RedisClientConfig;
import io.quarkus.redis.runtime.client.config.TlsConfig;
import io.quarkus.runtime.configuration.ConfigurationException;
import io.quarkus.tls.TlsConfiguration;
import io.quarkus.tls.TlsConfigurationRegistry;
import io.smallrye.common.annotation.Identifier;
import io.vertx.core.Vertx;
import io.vertx.core.buffer.Buffer;
import io.vertx.core.net.NetClientOptions;
import io.vertx.core.net.ProxyOptions;
import io.vertx.core.net.SSLOptions;
import io.vertx.redis.client.Redis;
import io.vertx.redis.client.RedisClientType;
import io.vertx.redis.client.RedisOptions;
Expand Down Expand Up @@ -113,32 +118,14 @@ private static NetClientOptions toNetClientOptions(RedisClientConfig config) {
TlsConfig tls = config.tls();
NetClientOptions net = new NetClientOptions();

tcp.alpn().ifPresent(net::setUseAlpn);
tcp.applicationLayerProtocols().ifPresent(net::setApplicationLayerProtocols);
tcp.connectionTimeout().ifPresent(d -> net.setConnectTimeout((int) d.toMillis()));

String verificationAlgorithm = tls.hostnameVerificationAlgorithm();
if ("NONE".equalsIgnoreCase(verificationAlgorithm)) {
net.setHostnameVerificationAlgorithm("");
} else {
net.setHostnameVerificationAlgorithm(verificationAlgorithm);
}

tcp.applicationLayerProtocols().ifPresent(net::setApplicationLayerProtocols);
tcp.connectionTimeout().ifPresent(d -> net.setConnectTimeout((int) d.toMillis()));
tcp.idleTimeout().ifPresent(d -> net.setIdleTimeout((int) d.toSeconds()));

tcp.keepAlive().ifPresent(b -> net.setTcpKeepAlive(true));
tcp.noDelay().ifPresent(b -> net.setTcpNoDelay(true));

net.setSsl(tls.enabled()).setTrustAll(tls.trustAll());

configurePemTrustOptions(net, tls.trustCertificatePem());
configureJksTrustOptions(net, tls.trustCertificateJks());
configurePfxTrustOptions(net, tls.trustCertificatePfx());

configurePemKeyCertOptions(net, tls.keyCertificatePem());
configureJksKeyCertOptions(net, tls.keyCertificateJks());
configurePfxKeyCertOptions(net, tls.keyCertificatePfx());

net.setReconnectAttempts(config.reconnectAttempts());
net.setReconnectInterval(config.reconnectInterval().toMillis());

Expand Down Expand Up @@ -191,4 +178,75 @@ public static RedisHostsProvider findProvider(String name) {
return providers.get();
}

private void configureTLS(String name, RedisClientConfig config, TlsConfigurationRegistry tlsRegistry, NetClientOptions net) {
TlsConfiguration configuration = null;

// Check if we have a named TLS configuration or a default configuration:
if (config.tlsConfigurationName().isPresent()) {
Optional<TlsConfiguration> maybeConfiguration = tlsRegistry.get(config.tlsConfigurationName().get());
if (!maybeConfiguration.isPresent()) {
throw new IllegalStateException("Unable to find the TLS configuration "
+ config.tlsConfigurationName().get() + " for the Redis client " + name + ".");
}
configuration = maybeConfiguration.get();
} else if (tlsRegistry.getDefault().isPresent() && tlsRegistry.getDefault().get().isTlsEnabled()) {
configuration = tlsRegistry.getDefault().get();
}

// Apply the configuration
if (configuration != null) {
// This part is often the same (or close) for every Vert.x client:
net.setSsl(true);

if (configuration.getTrustStoreOptions() != null) {
net.setTrustOptions(configuration.getTrustStoreOptions());
}

// For mTLS:
if (configuration.getKeyStoreOptions() != null) {
net.setKeyCertOptions(configuration.getKeyStoreOptions());
}

if (configuration.isTrustAll()) {
net.setTrustAll(true);
}
if (configuration.getHostnameVerificationAlgorithm().isPresent()) {
net.setHostnameVerificationAlgorithm(configuration.getHostnameVerificationAlgorithm().get());
}

SSLOptions sslOptions = configuration.getSSLOptions();
if (sslOptions != null) {
net.setSslHandshakeTimeout(sslOptions.getSslHandshakeTimeout());
net.setSslHandshakeTimeoutUnit(sslOptions.getSslHandshakeTimeoutUnit());
for (String suite : sslOptions.getEnabledCipherSuites()) {
net.addEnabledCipherSuite(suite);
}
for (Buffer buffer : sslOptions.getCrlValues()) {
net.addCrlValue(buffer);
}
net.setEnabledSecureTransportProtocols(sslOptions.getEnabledSecureTransportProtocols());
net.setUseAlpn(sslOptions.isUseAlpn());
}

} else {
config.tcp().alpn().ifPresent(net::setUseAlpn);

String verificationAlgorithm = config.tls().hostnameVerificationAlgorithm();
if ("NONE".equalsIgnoreCase(verificationAlgorithm)) {
net.setHostnameVerificationAlgorithm("");
} else {
net.setHostnameVerificationAlgorithm(verificationAlgorithm);
}
net.setSsl(config.tls().enabled()).setTrustAll(config.tls().trustAll());

configurePemTrustOptions(net, config.tls().trustCertificatePem());
configureJksTrustOptions(net, config.tls().trustCertificateJks());
configurePfxTrustOptions(net, config.tls().trustCertificatePfx());

configurePemKeyCertOptions(net, config.tls().keyCertificatePem());
configureJksKeyCertOptions(net, config.tls().keyCertificateJks());
configurePfxKeyCertOptions(net, config.tls().keyCertificatePfx());
}
}

}
Original file line number Diff line number Diff line change
Expand Up @@ -8,6 +8,7 @@
import io.quarkus.runtime.annotations.ConfigDocDefault;
import io.quarkus.runtime.annotations.ConfigDocSection;
import io.quarkus.runtime.annotations.ConfigGroup;
import io.quarkus.runtime.annotations.ConfigItem;
import io.smallrye.config.WithDefault;
import io.vertx.redis.client.ProtocolVersion;
import io.vertx.redis.client.RedisClientType;
Expand Down Expand Up @@ -168,6 +169,20 @@ public interface RedisClientConfig {
@ConfigDocSection
TlsConfig tls();

/**
* The name of the TLS configuration to use.
* <p>
* If not set and the default TLS configuration is configured ({@code quarkus.tls.*}) then that will be used.
* If a name is configured, it uses the configuration from {@code quarkus.tls.<name>.*}
* If a name is configured, but no TLS configuration is found with that name then an error will be thrown.
* <p>
* If no TLS configuration is set, and {@code quarkus.tls.*} is not configured, then,
* `quarkus.redis.$client-name.tls` will be used.
* <p>
* Important: This is only supported when using the Quarkus (Vert.x-based) gRPC client.
*/
Optional<String> tlsConfigurationName();

default String toDebugString() {
return "RedisClientConfig{" +
"hosts=" + hosts() +
Expand Down

0 comments on commit f81ef4f

Please sign in to comment.