Wire up the direct noise tunnel

This commit is contained in:
ravi-signal 2025-06-10 16:56:31 -05:00 committed by GitHub
parent 904cc63a72
commit 4ffd164461
No known key found for this signature in database
GPG Key ID: B5690EEEBB952194
5 changed files with 39 additions and 24 deletions

View File

@ -491,7 +491,8 @@ linkDevice:
secret: secret://linkDevice.secret
noiseTunnel:
port: 8443
webSocketPort: 8444
directPort: 8445
tlsKeyStoreFile: /path/to/file.p12
tlsKeyStoreEntryAlias: example.com
tlsKeyStorePassword: secret://noiseTunnel.tlsKeyStorePassword

View File

@ -43,7 +43,7 @@ import org.whispersystems.textsecuregcm.configuration.LinkDeviceSecretConfigurat
import org.whispersystems.textsecuregcm.configuration.MaxDeviceConfiguration;
import org.whispersystems.textsecuregcm.configuration.MessageByteLimitCardinalityEstimatorConfiguration;
import org.whispersystems.textsecuregcm.configuration.MessageCacheConfiguration;
import org.whispersystems.textsecuregcm.configuration.NoiseWebSocketTunnelConfiguration;
import org.whispersystems.textsecuregcm.configuration.NoiseTunnelConfiguration;
import org.whispersystems.textsecuregcm.configuration.OneTimeDonationConfiguration;
import org.whispersystems.textsecuregcm.configuration.PaymentsServiceConfiguration;
import org.whispersystems.textsecuregcm.configuration.RegistrationServiceClientFactory;
@ -304,7 +304,7 @@ public class WhisperServerConfiguration extends Configuration {
@Valid
@NotNull
@JsonProperty
private NoiseWebSocketTunnelConfiguration noiseTunnel;
private NoiseTunnelConfiguration noiseTunnel;
@Valid
@NotNull
@ -514,7 +514,7 @@ public class WhisperServerConfiguration extends Configuration {
return virtualThread;
}
public NoiseWebSocketTunnelConfiguration getNoiseWebSocketTunnelConfiguration() {
public NoiseTunnelConfiguration getNoiseTunnelConfiguration() {
return noiseTunnel;
}

View File

@ -154,6 +154,7 @@ import org.whispersystems.textsecuregcm.grpc.net.GrpcClientConnectionManager;
import org.whispersystems.textsecuregcm.grpc.net.ManagedDefaultEventLoopGroup;
import org.whispersystems.textsecuregcm.grpc.net.ManagedLocalGrpcServer;
import org.whispersystems.textsecuregcm.grpc.net.ManagedNioEventLoopGroup;
import org.whispersystems.textsecuregcm.grpc.net.noisedirect.NoiseDirectTunnelServer;
import org.whispersystems.textsecuregcm.grpc.net.websocket.NoiseWebSocketTunnelServer;
import org.whispersystems.textsecuregcm.jetty.JettyHttpConfigurationCustomizer;
import org.whispersystems.textsecuregcm.keytransparency.KeyTransparencyServiceClient;
@ -873,16 +874,17 @@ public class WhisperServerService extends Application<WhisperServerConfiguration
@Nullable final X509Certificate[] noiseWebSocketTlsCertificateChain;
@Nullable final PrivateKey noiseWebSocketTlsPrivateKey;
if (config.getNoiseWebSocketTunnelConfiguration().tlsKeyStoreFile() != null &&
config.getNoiseWebSocketTunnelConfiguration().tlsKeyStoreEntryAlias() != null &&
config.getNoiseWebSocketTunnelConfiguration().tlsKeyStorePassword() != null) {
if (config.getNoiseTunnelConfiguration().tlsKeyStoreFile() != null &&
config.getNoiseTunnelConfiguration().tlsKeyStoreEntryAlias() != null &&
config.getNoiseTunnelConfiguration().tlsKeyStorePassword() != null) {
try (final FileInputStream websocketNoiseTunnelTlsKeyStoreInputStream = new FileInputStream(config.getNoiseWebSocketTunnelConfiguration().tlsKeyStoreFile())) {
try (final FileInputStream websocketNoiseTunnelTlsKeyStoreInputStream = new FileInputStream(config.getNoiseTunnelConfiguration().tlsKeyStoreFile())) {
final KeyStore keyStore = KeyStore.getInstance("PKCS12");
keyStore.load(websocketNoiseTunnelTlsKeyStoreInputStream, config.getNoiseWebSocketTunnelConfiguration().tlsKeyStorePassword().value().toCharArray());
keyStore.load(websocketNoiseTunnelTlsKeyStoreInputStream, config.getNoiseTunnelConfiguration().tlsKeyStorePassword().value().toCharArray());
final KeyStore.PrivateKeyEntry privateKeyEntry = (KeyStore.PrivateKeyEntry) keyStore.getEntry(config.getNoiseWebSocketTunnelConfiguration().tlsKeyStoreEntryAlias(),
new KeyStore.PasswordProtection(config.getNoiseWebSocketTunnelConfiguration().tlsKeyStorePassword().value().toCharArray()));
final KeyStore.PrivateKeyEntry privateKeyEntry = (KeyStore.PrivateKeyEntry) keyStore.getEntry(
config.getNoiseTunnelConfiguration().tlsKeyStoreEntryAlias(),
new KeyStore.PasswordProtection(config.getNoiseTunnelConfiguration().tlsKeyStorePassword().value().toCharArray()));
noiseWebSocketTlsCertificateChain =
Arrays.copyOf(privateKeyEntry.getCertificateChain(), privateKeyEntry.getCertificateChain().length, X509Certificate[].class);
@ -901,27 +903,37 @@ public class WhisperServerService extends Application<WhisperServerConfiguration
.allowCoreThreadTimeOut(false)
.build();
final ManagedNioEventLoopGroup noiseWebSocketEventLoopGroup = new ManagedNioEventLoopGroup();
final ManagedNioEventLoopGroup noiseTunnelEventLoopGroup = new ManagedNioEventLoopGroup();
final NoiseWebSocketTunnelServer noiseWebSocketTunnelServer = new NoiseWebSocketTunnelServer(
config.getNoiseWebSocketTunnelConfiguration().port(),
config.getNoiseTunnelConfiguration().webSocketPort(),
noiseWebSocketTlsCertificateChain,
noiseWebSocketTlsPrivateKey,
noiseWebSocketEventLoopGroup,
noiseTunnelEventLoopGroup,
noiseWebSocketDelegatedTaskExecutor,
grpcClientConnectionManager,
clientPublicKeysManager,
config.getNoiseWebSocketTunnelConfiguration().noiseStaticKeyPair(),
config.getNoiseTunnelConfiguration().noiseStaticKeyPair(),
authenticatedGrpcServerAddress,
anonymousGrpcServerAddress,
config.getNoiseWebSocketTunnelConfiguration().recognizedProxySecret().value());
config.getNoiseTunnelConfiguration().recognizedProxySecret().value());
final NoiseDirectTunnelServer noiseDirectTunnelServer = new NoiseDirectTunnelServer(
config.getNoiseTunnelConfiguration().directPort(),
noiseTunnelEventLoopGroup,
grpcClientConnectionManager,
clientPublicKeysManager,
config.getNoiseTunnelConfiguration().noiseStaticKeyPair(),
authenticatedGrpcServerAddress,
anonymousGrpcServerAddress);
environment.lifecycle().manage(localEventLoopGroup);
environment.lifecycle().manage(dnsResolutionEventLoopGroup);
environment.lifecycle().manage(anonymousGrpcServer);
environment.lifecycle().manage(authenticatedGrpcServer);
environment.lifecycle().manage(noiseWebSocketEventLoopGroup);
environment.lifecycle().manage(noiseTunnelEventLoopGroup);
environment.lifecycle().manage(noiseWebSocketTunnelServer);
environment.lifecycle().manage(noiseDirectTunnelServer);
final List<Filter> filters = new ArrayList<>();
filters.add(remoteDeprecationFilter);

View File

@ -10,7 +10,8 @@ import org.signal.libsignal.protocol.ecc.ECPrivateKey;
import org.whispersystems.textsecuregcm.configuration.secrets.SecretBytes;
import org.whispersystems.textsecuregcm.configuration.secrets.SecretString;
public record NoiseWebSocketTunnelConfiguration(@Positive int port,
public record NoiseTunnelConfiguration(@Positive int webSocketPort,
@Positive int directPort,
@Nullable String tlsKeyStoreFile,
@Nullable String tlsKeyStoreEntryAlias,
@Nullable SecretString tlsKeyStorePassword,

View File

@ -485,7 +485,8 @@ linkDevice:
secret: secret://linkDevice.secret
noiseTunnel:
port: 8443
webSocketPort: 8444
directPort: 8445
noiseStaticPrivateKey: secret://noiseTunnel.noiseStaticPrivateKey
recognizedProxySecret: secret://noiseTunnel.recognizedProxySecret