Skip to content

Commit

Permalink
Merge pull request #13 from com2m/allow-multiple-aliases2
Browse files Browse the repository at this point in the history
Allow multiple aliases
  • Loading branch information
chke authored Feb 13, 2024
2 parents d84b753 + 6a4ce68 commit e310619
Show file tree
Hide file tree
Showing 7 changed files with 42 additions and 10 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -19,6 +19,7 @@
import com.hivemq.configuration.entity.listener.tls.ClientAuthenticationModeEntity;
import com.hivemq.configuration.entity.listener.tls.KeystoreEntity;
import com.hivemq.configuration.entity.listener.tls.TruststoreEntity;
import com.hivemq.configuration.entity.mqtt.MqttConfigurationDefaults;
import com.hivemq.extension.sdk.api.annotations.NotNull;
import com.hivemq.extension.sdk.api.annotations.Nullable;

Expand Down Expand Up @@ -60,6 +61,9 @@ public class TLSEntity {
@XmlElement(name = "cipher-suite")
private @NotNull List<String> cipherSuites = new ArrayList<>();

@XmlElement(name = "default-keystore-alias", defaultValue = "hivemq")
private String defaultKeystoreAlias = MqttConfigurationDefaults.DEFAULT_KEYSTORE_ALIAS;

@XmlElement(name = "prefer-server-cipher-suites")
private @Nullable Boolean preferServerCipherSuites = null;

Expand Down Expand Up @@ -91,4 +95,7 @@ public int getHandshakeTimeout() {
return preferServerCipherSuites;
}

public String getDefaultKeystoreAlias() {
return defaultKeystoreAlias;
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -48,4 +48,6 @@ public class MqttConfigurationDefaults {
public static final boolean KEEP_ALIVE_ALLOW_UNLIMITED_DEFAULT = true;
public static final int KEEP_ALIVE_MAX_DEFAULT = UnsignedDataTypes.UNSIGNED_SHORT_MAX_VALUE;

public static final String DEFAULT_KEYSTORE_ALIAS = "hivemq";

}
Original file line number Diff line number Diff line change
Expand Up @@ -182,6 +182,7 @@ private String getName(final @NotNull ListenerEntity entity, final @NotNull Stri
.withPreferServerCipherSuites(entity.isPreferServerCipherSuites())

.withHandshakeTimeout(entity.getHandshakeTimeout())
.withDefaultKeystoreAlias(entity.getDefaultKeystoreAlias())

.build();
}
Expand Down
17 changes: 15 additions & 2 deletions src/main/java/com/hivemq/configuration/service/entity/Tls.java
Original file line number Diff line number Diff line change
Expand Up @@ -45,6 +45,7 @@ public class Tls {
private final @NotNull List<String> protocols;
private final @NotNull List<String> cipherSuites;
private final @Nullable Boolean preferServerCipherSuites;
private final @Nullable String defaultKeystoreAlias;

/**
* Creates a new TLS configuration
Expand All @@ -63,6 +64,7 @@ public class Tls {
* @param cipherSuites the supported cipher suites. <code>null</code> means that all enabled cipher
* suites by the JVM are enabled
* @param preferServerCipherSuites if the server cipher suites are preferred over the client cipher suites
* @param defaultKeystoreAlias the default keystore alias to use if no sni name is given
* @since 3.3
*/
protected Tls(
Expand All @@ -77,7 +79,7 @@ protected Tls(
final @NotNull ClientAuthMode clientAuthMode,
final @NotNull List<String> protocols,
final @NotNull List<String> cipherSuites,
final @Nullable Boolean preferServerCipherSuites) {
final @Nullable Boolean preferServerCipherSuites, final String defaultKeystoreAlias) {

checkNotNull(clientAuthMode, "clientAuthMode must not be null");
checkNotNull(protocols, "protocols must not be null");
Expand All @@ -94,6 +96,7 @@ protected Tls(
this.protocols = protocols;
this.cipherSuites = cipherSuites;
this.preferServerCipherSuites = preferServerCipherSuites;
this.defaultKeystoreAlias = defaultKeystoreAlias;
}

/**
Expand Down Expand Up @@ -173,6 +176,9 @@ public int getHandshakeTimeout() {
return cipherSuites;
}

public @NotNull String getDefaultKeystoreAlias() {
return defaultKeystoreAlias;
}
/**
* @return if the server cipher suites should be preferred
*/
Expand Down Expand Up @@ -294,6 +300,7 @@ public static class Builder {
private @Nullable List<String> protocols;
private @Nullable List<String> cipherSuites;
private @Nullable Boolean preferServerCipherSuites;
private @Nullable String defaultKeystoreAlias;

public @NotNull Builder withKeystorePath(final @NotNull String keystorePath) {
this.keystorePath = keystorePath;
Expand Down Expand Up @@ -355,6 +362,11 @@ public static class Builder {
return this;
}

public @NotNull Builder withDefaultKeystoreAlias(final @NotNull String defaultKeystoreAlias) {
this.defaultKeystoreAlias = defaultKeystoreAlias;
return this;
}

public @NotNull Tls build() {
checkNotNull(keystorePath, "keystorePath must not be null");
checkNotNull(keystorePassword, "keystorePassword must not be null");
Expand All @@ -375,7 +387,8 @@ public static class Builder {
clientAuthMode,
protocols,
cipherSuites,
preferServerCipherSuites) {
preferServerCipherSuites,
defaultKeystoreAlias) {
};
}
}
Expand Down
15 changes: 12 additions & 3 deletions src/main/java/com/hivemq/security/ssl/SslContextFactory.java
Original file line number Diff line number Diff line change
Expand Up @@ -16,7 +16,9 @@

package com.hivemq.security.ssl;

import com.google.inject.Inject;
import com.hivemq.bootstrap.ioc.lazysingleton.LazySingleton;
import com.hivemq.configuration.service.SecurityConfigurationService;
import com.hivemq.configuration.service.entity.Tls;
import com.hivemq.extension.sdk.api.annotations.NotNull;
import com.hivemq.security.exception.SslException;
Expand Down Expand Up @@ -111,9 +113,16 @@ public PrivateKey getPrivateKey(final String alias) {
@Override
public String chooseEngineServerAlias(
final String keyType, final Principal[] issuers, final SSLEngine engine) {
final String certificateAlias = dnsResolver.resolve(engine.getPeerHost());
log.trace("Choose engine server alias for host: {} found alias: {}",
engine.getPeerHost(),
final String hostname = engine.getPeerHost();
final String certificateAlias;
if (hostname == null) {
// Without SNI activated the hostname is null, so we use the default alias
certificateAlias = tls.getDefaultKeystoreAlias();
log.debug("No SNI hostname given, using default alias: {}", certificateAlias);
} else {
certificateAlias = dnsResolver.resolve(hostname);
}
log.trace("Choose engine server alias for host: {} found alias: {}", hostname,
certificateAlias);
return certificateAlias;
}
Expand Down
8 changes: 4 additions & 4 deletions src/main/java/com/hivemq/security/ssl/SslSniHandler.java
Original file line number Diff line number Diff line change
Expand Up @@ -47,7 +47,7 @@ public class SslSniHandler extends SniHandler {
private final @NotNull Channel ch;
private final Consumer<Channel> idleHandlerFunction;
private final @NotNull SslFactory sslFactory;
private final @NotNull HashMap<String, SslHandler> aliasSslHandlerMap = new HashMap<>();
private final @NotNull HashMap<String, SslHandler> hostnameSslHandlerMap = new HashMap<>();

private final IdleStateHandler idleStateHandler;
private final NoTlsHandshakeIdleHandler noTlsHandshakeIdleHandler;
Expand Down Expand Up @@ -100,10 +100,10 @@ protected void replaceHandler(
try {
final int port = ClientConnectionContext.of(ctx.channel()).getConnectedListener().getPort();
log.trace("Replace ssl handler for hostname: {} and port: {}", hostname, port);
if (!aliasSslHandlerMap.containsKey(hostname)) {
aliasSslHandlerMap.put(hostname, sslFactory.getSslHandler(ch, tls, sslContext, hostname, port));
if (!hostnameSslHandlerMap.containsKey(hostname)) {
hostnameSslHandlerMap.put(hostname, sslFactory.getSslHandler(ch, tls, sslContext, hostname, port));
}
sslHandlerInstance = aliasSslHandlerMap.get(hostname);
sslHandlerInstance = hostnameSslHandlerMap.get(hostname);

sslHandlerInstance.handshakeFuture().addListener(future -> {
if (tls.getHandshakeTimeout() > 0) {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -54,4 +54,4 @@ protected void configure() {

}

}
}

0 comments on commit e310619

Please sign in to comment.