From 0eeb6605dbb856f56513e9fae153fa78528d8a42 Mon Sep 17 00:00:00 2001 From: Jon Chambers Date: Thu, 23 Jul 2026 18:26:14 -0400 Subject: [PATCH] Use a programmatically-generated keystore in `OmnibusH2ServerTest` --- .../grpc/net/OmnibusH2ServerTest.java | 51 +++++++++++++++--- .../generate-omnibus-h2-server-test-certs.sh | 19 ------- .../net/omnibus-h2-server-test-keystore.p12 | Bin 2658 -> 0 bytes 3 files changed, 45 insertions(+), 25 deletions(-) delete mode 100755 service/src/test/resources/org/whispersystems/textsecuregcm/grpc/net/generate-omnibus-h2-server-test-certs.sh delete mode 100644 service/src/test/resources/org/whispersystems/textsecuregcm/grpc/net/omnibus-h2-server-test-keystore.p12 diff --git a/service/src/test/java/org/whispersystems/textsecuregcm/grpc/net/OmnibusH2ServerTest.java b/service/src/test/java/org/whispersystems/textsecuregcm/grpc/net/OmnibusH2ServerTest.java index f5960cd45..142497c17 100644 --- a/service/src/test/java/org/whispersystems/textsecuregcm/grpc/net/OmnibusH2ServerTest.java +++ b/service/src/test/java/org/whispersystems/textsecuregcm/grpc/net/OmnibusH2ServerTest.java @@ -49,13 +49,18 @@ import io.netty.handler.ssl.ApplicationProtocolNames; import io.netty.handler.ssl.SslContext; import io.netty.handler.ssl.SslContextBuilder; import io.netty.handler.ssl.util.InsecureTrustManagerFactory; +import io.netty.pkitesting.CertificateBuilder; +import io.netty.util.Mapping; import io.netty.util.ReferenceCountUtil; import io.netty.util.test.LeakPresenceExtension; +import java.io.ByteArrayInputStream; +import java.io.ByteArrayOutputStream; import java.io.InputStream; import java.math.BigDecimal; import java.net.InetSocketAddress; import java.nio.charset.StandardCharsets; import java.time.Duration; +import java.time.Instant; import java.util.ArrayList; import java.util.Collections; import java.util.List; @@ -69,7 +74,10 @@ import java.util.function.Consumer; import java.util.stream.IntStream; import javax.annotation.Nullable; import javax.net.ssl.SSLException; +import org.apache.commons.lang3.RandomStringUtils; +import org.junit.jupiter.api.AfterAll; import org.junit.jupiter.api.AfterEach; +import org.junit.jupiter.api.BeforeAll; import org.junit.jupiter.api.BeforeEach; import org.junit.jupiter.api.Test; import org.junit.jupiter.api.extension.ExtendWith; @@ -80,20 +88,47 @@ import org.whispersystems.textsecuregcm.configuration.dynamic.DynamicOmnibusConf @ExtendWith(LeakPresenceExtension.class) class OmnibusH2ServerTest { - private static final String KEYSTORE_PASSWORD = "password"; - // Paths that start with PREFIX should go to the prefix backend, everything else to default. private static final String PREFIX_BACKEND_IDENTITY = "prefix-backend"; private static final String PREFIX = "/v1/prefix"; private static final String DEFAULT_BACKEND_IDENTITY = "default-backend"; - private final NioEventLoopGroup nioEventLoopGroup = new NioEventLoopGroup(); - private final DefaultEventLoopGroup localEventLoopGroup = new DefaultEventLoopGroup(); + private static NioEventLoopGroup nioEventLoopGroup; + private static DefaultEventLoopGroup localEventLoopGroup; + + private static Mapping sniMapping; private List backendChannelsToShutDown; private List omnibusH2ServersToShutDown; private AtomicReference dynamicConfiguration; + @BeforeAll + static void setUpBeforeAll() throws Exception { + final Instant now = Instant.now(); + + final char[] keyStorePassword = RandomStringUtils.insecure().nextAlphanumeric(16).toCharArray(); + final String domain = "foo.example.com"; + + final ByteArrayOutputStream byteArrayOutputStream = new ByteArrayOutputStream(); + + new CertificateBuilder() + .notBefore(now) + .notAfter(now.plus(Duration.ofDays(1))) + .setIsCertificateAuthority(true) + .algorithm(CertificateBuilder.Algorithm.rsa2048) + .subject("CN=" + domain) + .addSanDnsName(domain) + .buildSelfSigned() + .toKeyStore(keyStorePassword) + .store(byteArrayOutputStream, keyStorePassword); + + sniMapping = SniMapper.buildSniMapping(new ByteArrayInputStream(byteArrayOutputStream.toByteArray()), + new String(keyStorePassword)); + + nioEventLoopGroup = new NioEventLoopGroup(); + localEventLoopGroup = new DefaultEventLoopGroup(); + } + @BeforeEach void setUp() { backendChannelsToShutDown = new ArrayList<>(); @@ -102,9 +137,13 @@ class OmnibusH2ServerTest { } @AfterEach - void tearDown() throws Exception { + void tearDown() { omnibusH2ServersToShutDown.forEach(OmnibusH2Server::stop); backendChannelsToShutDown.forEach(c -> c.close().syncUninterruptibly()); + } + + @AfterAll + static void tearDownAfterAll() throws InterruptedException { localEventLoopGroup.shutdownGracefully(1, 1000, TimeUnit.MILLISECONDS).sync(); nioEventLoopGroup.shutdownGracefully(1, 1000, TimeUnit.MILLISECONDS).sync(); } @@ -443,7 +482,7 @@ class OmnibusH2ServerTest { backendChannelsToShutDown.add(defaultBackend); final OmnibusH2Server server = new OmnibusH2Server( - SniMapper.buildSniMapping(keyStore, KEYSTORE_PASSWORD), + sniMapping, nioEventLoopGroup, localEventLoopGroup, new InetSocketAddress("127.0.0.1", 0), diff --git a/service/src/test/resources/org/whispersystems/textsecuregcm/grpc/net/generate-omnibus-h2-server-test-certs.sh b/service/src/test/resources/org/whispersystems/textsecuregcm/grpc/net/generate-omnibus-h2-server-test-certs.sh deleted file mode 100755 index 5422e23bc..000000000 --- a/service/src/test/resources/org/whispersystems/textsecuregcm/grpc/net/generate-omnibus-h2-server-test-certs.sh +++ /dev/null @@ -1,19 +0,0 @@ -#!/bin/sh -# Generates self-signed local testing certificates for OmnibusH2ServerTest - -set -euo pipefail - -SCRIPT_DIR="$(cd "$(dirname "$0")" && pwd)" -WORK_DIR="$(mktemp -d)" -trap 'rm -rf "$WORK_DIR"' EXIT - -PASSWORD="password" -DAYS=36500 -OMNIBUS_KS="$SCRIPT_DIR/omnibus-h2-server-test-keystore.p12" - -openssl genpkey -algorithm RSA -pkeyopt rsa_keygen_bits:2048 -out "$WORK_DIR/foo-rsa.key" 2>/dev/null; -openssl req -new -x509 -key "$WORK_DIR/foo-rsa.key" -out "$WORK_DIR/foo-rsa.crt" -days "$DAYS" -subj "/CN=foo.example.com" -addext "subjectAltName=DNS:foo.example.com" -openssl pkcs12 -export -in "$WORK_DIR/foo-rsa.crt" -inkey "$WORK_DIR/foo-rsa.key" -out "$WORK_DIR/foo-rsa.p12" -name foo -passout pass:$PASSWORD -keytool -importkeystore -noprompt -srckeystore "$WORK_DIR/foo-rsa.p12" -srcstoretype PKCS12 -srcstorepass $PASSWORD -destkeystore "$OMNIBUS_KS" -deststoretype PKCS12 -deststorepass $PASSWORD - -echo "Wrote keystore to $OMNIBUS_KS" diff --git a/service/src/test/resources/org/whispersystems/textsecuregcm/grpc/net/omnibus-h2-server-test-keystore.p12 b/service/src/test/resources/org/whispersystems/textsecuregcm/grpc/net/omnibus-h2-server-test-keystore.p12 deleted file mode 100644 index 3e6200dd89d301df2206ddf776454fefcf216117..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 2658 zcma);XHXLg633Ge0)!SiJRv3m^5_W&_~<;URFMu+q>5DOpr`~vLhrpxMSR z29akXC-vm zxtd#t_8HJ{lLBlT*3mT0K^c2JAh{*b%AIo+nEou6U*P zDdjh;RSJ1PP;#`gITrPztI0R}7Geey0O+V1bOs+TbeEa2W0#uuL2aErHx;<~ivWDa6su?c!In~jQ;N_M0> zAIZ;QlNK1G6-Zt-O!b-A{;7oXy&JKO)M3hG96lIRO-;$9pl4X|hz8Er@7x%T5cDXH z4dLA9Rq=)g&17U>ZGwjuLhCnwMv!oAah*@r6wTRrOT*MXBx|C%qiZ?Hioah1zdwViaX4XbV3X?%-cUFM}&&#K{$>mwFEu3*fTOgCDnBFk$QlI*Z6-!}>V zT;%+EmRm$W*nMs$(e-Fza~82`31<}ONoKj);2zyKNDw*mWMh@G2OCdC!!r4|zx&gS z?y%i-eS=0V+3IRNtGzLNzRsbjJjC`TsMF!3jIXPf>gyYBsWX=(|9pbhuuc7T@(aBz zk7z--zmUv0-|}MVYC}9Q?u%fek4L9G1Vlgg7s6}8ebK3wuk$U=8VWAFUFXUn7F9JU z*`&h0JtsX$aCPaO5&tGoA?%(`^xs#BewR=Hh;~=Gplta`ep&lEV0w_o(4m=bi#2S; z*jbLRY+<^&<{4CvXdoum_Ijwh#2f5WCSDCS()J{|1zp!v-T=E1`&mHZW=*3=O6~%{ z-f4EI?a>k$fm?dODHt!RT&6^=4WCKL(`R+d;_fZ;&R>Xhbm^LDwf^%F2G=7yrOgG# z>TDYx@JG_9!;BIrAXQ~MFBPHjBoTL#R=`5*eKruF6BkIX%g&z-2sdUP!M19r!o zCdf^aTiF)q8rIWsK8S+!gGbB<+llP-XIWc`zJ_5JZBc3JF8kpPavXAu?>5b1mK_N) z?fYm+6w@zUQZS;);Shj5zzyJrLjIPS(2QVueMc8N1X@BuTtY+yEh;J^E{?*06@E35 zL2@x*k!wi^1O!|sp5G4ee*s#rklxQLo9QVt@moKh<5|JPQvBop2hf~!&gfbn$yJGT z`#O{7$evdi5*&*o@Hw`{n9m`QsDiywx!`avcnx{0$I?ntUa1&!%wP(So!I@V8y&OC zagKalK4ZQ%VS@s^@E?o9Lx{Pr_$mX9W9@D44RHs;sF%m;fm`=_#iIuE%*jbE9~sSy z#I|-N#H6h4j-@VBbl;t+vI$ytKW$sQv_sDFz!!UZ_g=+QMV|ah|4H8Bn1<5w`9=l6 z2>%~xJx*(DBgq5Yn7`+baVc|`{#Vw^2-syHr$uh_{eW-g-r9AQ9xa`rb^vHpjKVfs zvC+lPCNkQN-TOtU)Y;C5!g?AFH>8vU7RUS}=4f?rYOm1L61I$PIIN(vI!Mezy^b$< znnVFN+1^b0+?gsoRPoE<*@=uKPv<#Lx^su_q#@QFcU1{z&gGSe(yoet%xSDMD8;&c zGLA0yGcCf!Yu}$t)y+{6U|YoAvDLZ+vY9liWmIB6o9*G29^h$1YwILP#SZQWv%Xx6$%`g?9yl5DNMita%JHCa z(ilXvAfce@Q@@;)SDNUjj!tO>@POoBFh!c(0|&xI&BCJ~$_;Z5 z1<9FX*bB>lOd#dPj=MfLREx{*Uo91%Mku{*b_%2zW!sU(!#^FtZyd|X5Jz6TFWS~<{^90nUOyQ*I2 zvTRrkoZ4l5L>KNBFI^rnU3% zE#?I%4VN|+RO>4(o;Esu?&rrB$2eP->?JB{GV?ZP7eZB!9ro9(Q>g2u^af20{?6iP z6lYrH!PgKV?hl~vHO|veS|~J%`q$qD0+Is2h`bJC>Xl|m&txI1zuSC6ZhqfM?_84_ nos*`^oA*kbl?5}h{z*1P2%4>(slKC`dl|T8m9G>3FJ$}^W>(J`