Skip to content

Commit 7f29ebf

Browse files
committed
feat(pqc): upgrade gRPC to v1.83.0 and add gRPC PQC Showcase integration tests
- Upgrade <grpc.version> from 1.82.2 to 1.83.0 in gapic-generator-java-pom-parent and grpc-gcp-java. - Upgrade <gson.version> to 2.14.0 and <errorprone.version> to 2.50.0 to satisfy Maven Enforcer rules for gRPC 1.83.0. - Add testGrpcPqc_withTls Showcase TLS integration test in ITPostQuantumCryptography.java using built-in default gRPC transport, configured to trust the Showcase TLS server certificate directly. - Include concise Javadoc documenting gRPC 1.83.0 built-in PQC behavior and explaining the purpose of GrpcTlsCapturingClientInterceptor and HTTP/2 metadata helper methods. - Simplify GrpcTlsCapturingClientInterceptor to only capture initial response headers (onHeaders). - Assert negotiated group is equal to EXPECTED_PQC_GROUP for gRPC without asserting a supported groups list. - Leave all HTTP/JSON tests and setUp() 100% untouched. - Exclude all mTLS test resources, keys, certs, and mTLS logic. TAG=agy CONV=385b9ab5-874c-4c9a-b331-66dab51fef61
1 parent 12cc053 commit 7f29ebf

4 files changed

Lines changed: 120 additions & 6 deletions

File tree

google-auth-library-java/pom.xml

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -80,7 +80,7 @@
8080
<project.appengine.version>2.0.33</project.appengine.version>
8181
<project.findbugs.version>3.0.2</project.findbugs.version>
8282
<deploy.autorelease>false</deploy.autorelease>
83-
<project.error-prone.version>2.48.0</project.error-prone.version>
83+
<project.error-prone.version>2.50.0</project.error-prone.version>
8484
<project.protobuf.version>4.33.6</project.protobuf.version>
8585
<project.cel.version>0.9.0-proto3</project.cel.version>
8686
<project.tink.version>1.15.0</project.tink.version>

grpc-gcp-java/pom.xml

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -66,10 +66,10 @@
6666
<auto-value.version>1.11.0</auto-value.version>
6767
<error-prone-annotations.version>2.48.0</error-prone-annotations.version>
6868
<google-http-client.version>2.2.0</google-http-client.version>
69-
<gson.version>2.13.2</gson.version>
69+
<gson.version>2.14.0</gson.version>
7070
<guava.version>33.6.0-jre</guava.version>
7171
<protobuf.version>4.33.6</protobuf.version>
72-
<grpc.version>1.82.2</grpc.version>
72+
<grpc.version>1.83.0</grpc.version>
7373
<jsr305.version>3.0.2</jsr305.version>
7474
<junit.version>4.13.2</junit.version>
7575
<opencensus.version>0.31.1</opencensus.version>

java-showcase/gapic-showcase/src/test/java/com/google/showcase/v1beta1/it/ITPostQuantumCryptography.java

Lines changed: 114 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -29,6 +29,17 @@
2929
import com.google.showcase.v1beta1.EchoResponse;
3030
import com.google.showcase.v1beta1.EchoSettings;
3131
import com.google.showcase.v1beta1.it.util.HttpJsonCapturingClientInterceptor;
32+
import com.google.api.gax.grpc.InstantiatingGrpcChannelProvider;
33+
import io.grpc.CallOptions;
34+
import io.grpc.Channel;
35+
import io.grpc.ClientCall;
36+
import io.grpc.ClientInterceptor;
37+
import io.grpc.ForwardingClientCall;
38+
import io.grpc.ForwardingClientCallListener;
39+
import io.grpc.Metadata;
40+
import io.grpc.MethodDescriptor;
41+
import io.grpc.netty.shaded.io.grpc.netty.GrpcSslContexts;
42+
import io.grpc.netty.shaded.io.grpc.netty.NettyChannelBuilder;
3243
import java.io.File;
3344
import java.io.InputStream;
3445
import java.nio.file.Files;
@@ -266,4 +277,107 @@ private static KeyStore loadCaCert(String certPath) throws Exception {
266277
}
267278
return trustStore;
268279
}
280+
281+
/**
282+
* Integration test to verify Post-Quantum Cryptography (PQC) TLS negotiation for gRPC clients.
283+
*
284+
* <p>In gRPC-Java 1.83.0+, the default Netty transport (`grpc-netty-shaded`) bundles BoringSSL
285+
* (`netty-tcnative-boringssl-static`) with built-in PQC hybrid key exchange support (e.g.,
286+
* X25519MLKEM768). No custom socket configurator or security provider swapping is needed.
287+
*
288+
* <p>Because the local Showcase test server uses a self-signed CA certificate (written to
289+
* {@link #DEFAULT_CA_CERT_PATH}), we configure the gRPC transport channel builder directly to
290+
* trust this certificate via {@link GrpcSslContexts#forClient()}. This avoids mutating global JVM
291+
* system properties in {@code setUp()} and ensures HTTP/JSON tests remain completely isolated.
292+
*/
293+
@Test
294+
void testGrpcPqc_withTls() throws Exception {
295+
GrpcTlsCapturingClientInterceptor interceptor = new GrpcTlsCapturingClientInterceptor();
296+
297+
InstantiatingGrpcChannelProvider transportChannelProvider =
298+
EchoSettings.defaultGrpcTransportProviderBuilder()
299+
.setEndpoint(SECURE_ENDPOINT)
300+
.setInterceptorProvider(() -> Collections.singletonList(interceptor))
301+
.setChannelConfigurator(
302+
managedChannelBuilder -> {
303+
if (managedChannelBuilder instanceof NettyChannelBuilder) {
304+
try {
305+
// Explicitly trust the self-signed CA certificate created by the local
306+
// Showcase TLS connection without altering JVM-wide SSL trust stores.
307+
((NettyChannelBuilder) managedChannelBuilder)
308+
.sslContext(
309+
GrpcSslContexts.forClient()
310+
.trustManager(new File(DEFAULT_CA_CERT_PATH))
311+
.build());
312+
} catch (Exception e) {
313+
throw new RuntimeException("Failed to configure gRPC SSL context", e);
314+
}
315+
}
316+
return managedChannelBuilder;
317+
})
318+
.build();
319+
320+
EchoSettings settings =
321+
EchoSettings.newBuilder()
322+
.setCredentialsProvider(NoCredentialsProvider.create())
323+
.setTransportChannelProvider(transportChannelProvider)
324+
.build();
325+
326+
try (EchoClient client = EchoClient.create(settings)) {
327+
EchoResponse response =
328+
client.echo(EchoRequest.newBuilder().setContent("pqc-grpc-tls-test").build());
329+
assertThat(response.getContent()).isEqualTo("pqc-grpc-tls-test");
330+
331+
Metadata capturedHeaders = interceptor.capturedMetadata;
332+
assertThat(capturedHeaders).isNotNull();
333+
334+
// Verify that TLS 1.3 key exchange negotiated the expected PQC hybrid group (X25519MLKEM768).
335+
String negotiatedGroup = getGrpcSingleHeaderString(capturedHeaders, TLS_GROUP_HEADER);
336+
assertThat(negotiatedGroup).isEqualTo(EXPECTED_PQC_GROUP);
337+
}
338+
}
339+
340+
/**
341+
* Private gRPC client interceptor to capture the response headers from the Showcase server to
342+
* verify the PQC algorithm.
343+
*/
344+
private static class GrpcTlsCapturingClientInterceptor implements ClientInterceptor {
345+
final Metadata capturedMetadata = new Metadata();
346+
347+
@Override
348+
public <ReqT, RespT> ClientCall<ReqT, RespT> interceptCall(
349+
MethodDescriptor<ReqT, RespT> method,
350+
CallOptions callOptions,
351+
Channel next) {
352+
return new ForwardingClientCall.SimpleForwardingClientCall<ReqT, RespT>(
353+
next.newCall(method, callOptions)) {
354+
@Override
355+
public void start(Listener<RespT> responseListener, Metadata headers) {
356+
super.start(
357+
new ForwardingClientCallListener.SimpleForwardingClientCallListener<RespT>(
358+
responseListener) {
359+
@Override
360+
public void onHeaders(Metadata headers) {
361+
capturedMetadata.merge(headers);
362+
super.onHeaders(headers);
363+
}
364+
},
365+
headers);
366+
}
367+
};
368+
}
369+
}
370+
371+
/**
372+
* Private helper method required to extract a single string header from gRPC {@link Metadata}.
373+
*
374+
* @param metadata the captured gRPC response metadata
375+
* @param name the case-insensitive HTTP/2 header name
376+
* @return the string header value, or {@code null} if not present
377+
*/
378+
private static String getGrpcSingleHeaderString(Metadata metadata, String name) {
379+
Metadata.Key<String> key =
380+
Metadata.Key.of(name, Metadata.ASCII_STRING_MARSHALLER);
381+
return metadata.get(key);
382+
}
269383
}

sdk-platform-java/gapic-generator-java-pom-parent/pom.xml

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -27,13 +27,13 @@
2727
<!-- External dependencies, especially gRPC and Protobuf version, should be
2828
consistent across modules in this repository -->
2929
<javax.annotation-api.version>1.3.2</javax.annotation-api.version>
30-
<grpc.version>1.82.2</grpc.version>
30+
<grpc.version>1.83.0</grpc.version>
3131
<google.http-client.version>2.2.0</google.http-client.version>
32-
<gson.version>2.13.2</gson.version>
32+
<gson.version>2.14.0</gson.version>
3333
<guava.version>33.6.0-jre</guava.version>
3434
<protobuf.version>4.33.6</protobuf.version>
3535
<opentelemetry.version>1.62.0</opentelemetry.version>
36-
<errorprone.version>2.48.0</errorprone.version>
36+
<errorprone.version>2.50.0</errorprone.version>
3737
<jspecify.version>1.0.0</jspecify.version>
3838
<j2objc-annotations.version>3.1</j2objc-annotations.version>
3939
<threetenbp.version>1.7.0</threetenbp.version>

0 commit comments

Comments
 (0)