Skip to content

Commit 67c504f

Browse files
Merge branch 'master' into FixIssue-11194
# Conflicts: # services/src/main/java/io/grpc/protobuf/services/HealthCheckingLoadBalancerFactory.java
2 parents e6bea7f + fd5263f commit 67c504f

File tree

36 files changed

+1626
-649
lines changed

36 files changed

+1626
-649
lines changed
Lines changed: 24 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,24 @@
1+
/*
2+
* Copyright 2025 The gRPC Authors
3+
*
4+
* Licensed under the Apache License, Version 2.0 (the "License");
5+
* you may not use this file except in compliance with the License.
6+
* You may obtain a copy of the License at
7+
*
8+
* http://www.apache.org/licenses/LICENSE-2.0
9+
*
10+
* Unless required by applicable law or agreed to in writing, software
11+
* distributed under the License is distributed on an "AS IS" BASIS,
12+
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13+
* See the License for the specific language governing permissions and
14+
* limitations under the License.
15+
*/
16+
17+
package io.grpc.internal;
18+
19+
import io.grpc.Status;
20+
21+
/** Verifier for the outgoing authority pseudo-header against peer cert. */
22+
public interface AuthorityVerifier {
23+
Status verifyAuthority(String authority);
24+
}
Lines changed: 66 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,66 @@
1+
/*
2+
* Copyright 2024 The gRPC Authors
3+
*
4+
* Licensed under the Apache License, Version 2.0 (the "License");
5+
* you may not use this file except in compliance with the License.
6+
* You may obtain a copy of the License at
7+
*
8+
* http://www.apache.org/licenses/LICENSE-2.0
9+
*
10+
* Unless required by applicable law or agreed to in writing, software
11+
* distributed under the License is distributed on an "AS IS" BASIS,
12+
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13+
* See the License for the specific language governing permissions and
14+
* limitations under the License.
15+
*/
16+
17+
package io.grpc.internal;
18+
19+
import java.io.IOException;
20+
import java.io.InputStream;
21+
import java.security.GeneralSecurityException;
22+
import java.security.KeyStore;
23+
import java.security.cert.Certificate;
24+
import java.security.cert.CertificateException;
25+
import java.security.cert.CertificateFactory;
26+
import java.security.cert.X509Certificate;
27+
import java.util.Collection;
28+
import javax.net.ssl.TrustManager;
29+
import javax.net.ssl.TrustManagerFactory;
30+
import javax.security.auth.x500.X500Principal;
31+
32+
/**
33+
* Contains certificate/key PEM file utility method(s) for internal usage.
34+
*/
35+
public final class CertificateUtils {
36+
/**
37+
* Creates X509TrustManagers using the provided CA certs.
38+
*/
39+
public static TrustManager[] createTrustManager(InputStream rootCerts)
40+
throws GeneralSecurityException {
41+
KeyStore ks = KeyStore.getInstance(KeyStore.getDefaultType());
42+
try {
43+
ks.load(null, null);
44+
} catch (IOException ex) {
45+
// Shouldn't really happen, as we're not loading any data.
46+
throw new GeneralSecurityException(ex);
47+
}
48+
X509Certificate[] certs = CertificateUtils.getX509Certificates(rootCerts);
49+
for (X509Certificate cert : certs) {
50+
X500Principal principal = cert.getSubjectX500Principal();
51+
ks.setCertificateEntry(principal.getName("RFC2253"), cert);
52+
}
53+
54+
TrustManagerFactory trustManagerFactory =
55+
TrustManagerFactory.getInstance(TrustManagerFactory.getDefaultAlgorithm());
56+
trustManagerFactory.init(ks);
57+
return trustManagerFactory.getTrustManagers();
58+
}
59+
60+
private static X509Certificate[] getX509Certificates(InputStream inputStream)
61+
throws CertificateException {
62+
CertificateFactory factory = CertificateFactory.getInstance("X.509");
63+
Collection<? extends Certificate> certs = factory.generateCertificates(inputStream);
64+
return certs.toArray(new X509Certificate[0]);
65+
}
66+
}

core/src/main/java/io/grpc/internal/GrpcAttributes.java

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -42,5 +42,8 @@ public final class GrpcAttributes {
4242
public static final Attributes.Key<Attributes> ATTR_CLIENT_EAG_ATTRS =
4343
Attributes.Key.create("io.grpc.internal.GrpcAttributes.clientEagAttrs");
4444

45+
public static final Attributes.Key<AuthorityVerifier> ATTR_AUTHORITY_VERIFIER =
46+
Attributes.Key.create("io.grpc.internal.GrpcAttributes.authorityVerifier");
47+
4548
private GrpcAttributes() {}
4649
}
Lines changed: 132 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,132 @@
1+
/*
2+
* Copyright 2024 The gRPC Authors
3+
*
4+
* Licensed under the Apache License, Version 2.0 (the "License");
5+
* you may not use this file except in compliance with the License.
6+
* You may obtain a copy of the License at
7+
*
8+
* http://www.apache.org/licenses/LICENSE-2.0
9+
*
10+
* Unless required by applicable law or agreed to in writing, software
11+
* distributed under the License is distributed on an "AS IS" BASIS,
12+
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13+
* See the License for the specific language governing permissions and
14+
* limitations under the License.
15+
*/
16+
17+
package io.grpc.internal;
18+
19+
import java.security.Principal;
20+
import java.security.cert.Certificate;
21+
import javax.net.ssl.SSLPeerUnverifiedException;
22+
import javax.net.ssl.SSLSession;
23+
import javax.net.ssl.SSLSessionContext;
24+
25+
/** A no-op ssl session, to facilitate overriding only the required methods in specific
26+
* implementations.
27+
*/
28+
public class NoopSslSession implements SSLSession {
29+
@Override
30+
public byte[] getId() {
31+
return new byte[0];
32+
}
33+
34+
@Override
35+
public SSLSessionContext getSessionContext() {
36+
return null;
37+
}
38+
39+
@Override
40+
@SuppressWarnings("deprecation")
41+
public javax.security.cert.X509Certificate[] getPeerCertificateChain() {
42+
throw new UnsupportedOperationException("This method is deprecated and marked for removal. "
43+
+ "Use the getPeerCertificates() method instead.");
44+
}
45+
46+
@Override
47+
public long getCreationTime() {
48+
return 0;
49+
}
50+
51+
@Override
52+
public long getLastAccessedTime() {
53+
return 0;
54+
}
55+
56+
@Override
57+
public void invalidate() {
58+
}
59+
60+
@Override
61+
public boolean isValid() {
62+
return false;
63+
}
64+
65+
@Override
66+
public void putValue(String s, Object o) {
67+
}
68+
69+
@Override
70+
public Object getValue(String s) {
71+
return null;
72+
}
73+
74+
@Override
75+
public void removeValue(String s) {
76+
}
77+
78+
@Override
79+
public String[] getValueNames() {
80+
return new String[0];
81+
}
82+
83+
@Override
84+
public Certificate[] getPeerCertificates() throws SSLPeerUnverifiedException {
85+
return new Certificate[0];
86+
}
87+
88+
@Override
89+
public Certificate[] getLocalCertificates() {
90+
return new Certificate[0];
91+
}
92+
93+
@Override
94+
public Principal getPeerPrincipal() throws SSLPeerUnverifiedException {
95+
return null;
96+
}
97+
98+
@Override
99+
public Principal getLocalPrincipal() {
100+
return null;
101+
}
102+
103+
@Override
104+
public String getCipherSuite() {
105+
return null;
106+
}
107+
108+
@Override
109+
public String getProtocol() {
110+
return null;
111+
}
112+
113+
@Override
114+
public String getPeerHost() {
115+
return null;
116+
}
117+
118+
@Override
119+
public int getPeerPort() {
120+
return 0;
121+
}
122+
123+
@Override
124+
public int getPacketBufferSize() {
125+
return 0;
126+
}
127+
128+
@Override
129+
public int getApplicationBufferSize() {
130+
return 0;
131+
}
132+
}

interop-testing/src/main/java/io/grpc/testing/integration/RpcBehaviorLoadBalancerProvider.java

Lines changed: 7 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -116,6 +116,13 @@ public Status acceptResolvedAddresses(ResolvedAddresses resolvedAddresses) {
116116
((RpcBehaviorConfig) resolvedAddresses.getLoadBalancingPolicyConfig()).rpcBehavior);
117117
return delegateLb.acceptResolvedAddresses(resolvedAddresses);
118118
}
119+
120+
@Override
121+
public Status acceptResolvedAddresses(ResolvedAddresses resolvedAddresses) {
122+
helper.setRpcBehavior(
123+
((RpcBehaviorConfig) resolvedAddresses.getLoadBalancingPolicyConfig()).rpcBehavior);
124+
return delegateLb.acceptResolvedAddresses(resolvedAddresses);
125+
}
119126
}
120127

121128
/**

interop-testing/src/test/java/io/grpc/testing/integration/RpcBehaviorLoadBalancerProviderTest.java

Lines changed: 9 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -87,6 +87,15 @@ public void handleResolvedAddressesDelegated() {
8787
verify(mockDelegateLb).acceptResolvedAddresses(resolvedAddresses);
8888
}
8989

90+
@Test
91+
public void acceptResolvedAddressesDelegated() {
92+
RpcBehaviorLoadBalancer lb = new RpcBehaviorLoadBalancer(new RpcBehaviorHelper(mockHelper),
93+
mockDelegateLb);
94+
ResolvedAddresses resolvedAddresses = buildResolvedAddresses(buildConfig());
95+
lb.acceptResolvedAddresses(resolvedAddresses);
96+
verify(mockDelegateLb).acceptResolvedAddresses(resolvedAddresses);
97+
}
98+
9099
@Test
91100
public void helperWrapsPicker() {
92101
RpcBehaviorHelper helper = new RpcBehaviorHelper(mockHelper);

netty/src/main/java/io/grpc/netty/GrpcHttp2OutboundHeaders.java

Lines changed: 10 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -66,6 +66,16 @@ private GrpcHttp2OutboundHeaders(AsciiString[] preHeaders, byte[][] serializedMe
6666
this.preHeaders = preHeaders;
6767
}
6868

69+
@Override
70+
public CharSequence authority() {
71+
for (int i = 0; i < preHeaders.length / 2; i++) {
72+
if (preHeaders[i * 2].equals(Http2Headers.PseudoHeaderName.AUTHORITY.value())) {
73+
return preHeaders[i * 2 + 1];
74+
}
75+
}
76+
return null;
77+
}
78+
6979
@Override
7080
@SuppressWarnings("ReferenceEquality") // STATUS.value() never changes.
7181
public CharSequence status() {

netty/src/main/java/io/grpc/netty/InternalProtocolNegotiators.java

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -44,7 +44,7 @@ public static InternalProtocolNegotiator.ProtocolNegotiator tls(SslContext sslCo
4444
ObjectPool<? extends Executor> executorPool,
4545
Optional<Runnable> handshakeCompleteRunnable) {
4646
final io.grpc.netty.ProtocolNegotiator negotiator = ProtocolNegotiators.tls(sslContext,
47-
executorPool, handshakeCompleteRunnable);
47+
executorPool, handshakeCompleteRunnable, null);
4848
final class TlsNegotiator implements InternalProtocolNegotiator.ProtocolNegotiator {
4949

5050
@Override
@@ -170,7 +170,7 @@ public static ChannelHandler clientTlsHandler(
170170
ChannelHandler next, SslContext sslContext, String authority,
171171
ChannelLogger negotiationLogger) {
172172
return new ClientTlsHandler(next, sslContext, authority, null, negotiationLogger,
173-
Optional.absent());
173+
Optional.absent(), null, null);
174174
}
175175

176176
public static class ProtocolNegotiationHandler

netty/src/main/java/io/grpc/netty/NettyChannelBuilder.java

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -652,7 +652,7 @@ static ProtocolNegotiator createProtocolNegotiatorByType(
652652
case PLAINTEXT_UPGRADE:
653653
return ProtocolNegotiators.plaintextUpgrade();
654654
case TLS:
655-
return ProtocolNegotiators.tls(sslContext, executorPool, Optional.absent());
655+
return ProtocolNegotiators.tls(sslContext, executorPool, Optional.absent(), null);
656656
default:
657657
throw new IllegalArgumentException("Unsupported negotiationType: " + negotiationType);
658658
}

0 commit comments

Comments
 (0)