Skip to content

Commit c276c35

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 c276c35

4 files changed

Lines changed: 117 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: 111 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -21,6 +21,7 @@
2121

2222
import com.google.api.client.http.javanet.NetHttpTransport;
2323
import com.google.api.gax.core.NoCredentialsProvider;
24+
import com.google.api.gax.grpc.InstantiatingGrpcChannelProvider;
2425
import com.google.api.gax.httpjson.HttpJsonConscryptUtils;
2526
import com.google.api.gax.httpjson.HttpJsonMetadata;
2627
import com.google.api.gax.httpjson.InstantiatingHttpJsonChannelProvider;
@@ -29,6 +30,16 @@
2930
import com.google.showcase.v1beta1.EchoResponse;
3031
import com.google.showcase.v1beta1.EchoSettings;
3132
import com.google.showcase.v1beta1.it.util.HttpJsonCapturingClientInterceptor;
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,104 @@ 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 {@link
289+
* #DEFAULT_CA_CERT_PATH}), we configure the gRPC transport channel builder directly to trust this
290+
* certificate via {@link GrpcSslContexts#forClient()}. This avoids mutating global JVM system
291+
* 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, CallOptions callOptions, Channel next) {
350+
return new ForwardingClientCall.SimpleForwardingClientCall<ReqT, RespT>(
351+
next.newCall(method, callOptions)) {
352+
@Override
353+
public void start(Listener<RespT> responseListener, Metadata headers) {
354+
super.start(
355+
new ForwardingClientCallListener.SimpleForwardingClientCallListener<RespT>(
356+
responseListener) {
357+
@Override
358+
public void onHeaders(Metadata headers) {
359+
capturedMetadata.merge(headers);
360+
super.onHeaders(headers);
361+
}
362+
},
363+
headers);
364+
}
365+
};
366+
}
367+
}
368+
369+
/**
370+
* Private helper method required to extract a single string header from gRPC {@link Metadata}.
371+
*
372+
* @param metadata the captured gRPC response metadata
373+
* @param name the case-insensitive HTTP/2 header name
374+
* @return the string header value, or {@code null} if not present
375+
*/
376+
private static String getGrpcSingleHeaderString(Metadata metadata, String name) {
377+
Metadata.Key<String> key = Metadata.Key.of(name, Metadata.ASCII_STRING_MARSHALLER);
378+
return metadata.get(key);
379+
}
269380
}

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)