镜像站点 · 本页由第三方 GitHub 只读镜像提供,非 GitHub 官方站点,不接受任何登录或凭据输入。前往 github.com
Skip to content

Future-proof and flexible hostname verification #12343

Closed

Description

@chrisvest

In Netty 4.2 we changed the default endpoint identification algorithm to “HTTPS”, thereby enabling hostname verification by default.
This has no effect on gRPC-Java, because it was already always enabling hostname verification:

@Override
@IgnoreJRERequirement
protected void handlerAdded0(ChannelHandlerContext ctx) {
sslEngine = sslContext.newEngine(ctx.alloc(), host, port);
SSLParameters sslParams = sslEngine.getSSLParameters();
sslParams.setEndpointIdentificationAlgorithm("HTTPS");
sslEngine.setSSLParameters(sslParams);
ctx.pipeline().addBefore(ctx.name(), /* name= */ null, this.executor != null
? new SslHandler(sslEngine, false, this.executor)
: new SslHandler(sslEngine, false));
}

Unfortunately, the above means gRPC-Java doesn’t offer any nice way to disable hostname verification in situations where the client expects a non-DNS identity from the server, such as a SPIFFE in a URI SAN.
A client that wishes to authenticate non-DNS identities needs to implement a custom TrustManager that nerfs out the endpoint identification algorithm in the provided SSLEngine, before proceeding with the authentication procedure. When we use the OPENSSL provider, this adds an extra JNI call per handshake that could otherwise be avoided.

A better approach would be to configure the endpoint identification algorithm in the SslContextBuilder. Since Netty 4.1.112, we’ve been exposing this as a configuration method:
https://netty.io/4.1/api/io/netty/handler/ssl/SslContextBuilder.html#endpointIdentificationAlgorithm-java.lang.String-

The GrpcSslContexts class in gRPC-Java already provides ssl context builder objects with sane defaults that people are encouraged to use. It makes sense that it would provide instances to clients that have the “HTTPS” endpoint identification algorithm pre-configured. Clients could then choose to opt out of hostname verification if they need to.

Now, with the above proposed change, if people don’t use the GrpcSslContexts class but instead create their own SslContextBuilder, then it’s possible that they were previously protected by hostname verification but now no longer are.
It is possible to issue or log a warning, in that case. There are two ways to disable hostname verification: 1) the endpoint identification algorithm can be null (the default in 4.1), or 2) the algorithm can be the empty string. In gRPC-Java, we can use these to distinguish between a poor default, null, and intentionally opting out of hostname verification with the empty string.
Alternatively, gRPC-Java can overwrite the null values to preserve the default safety it currently enjoy, and then accept the empty string as an intentional choice to opt out.

By removing the code in the ClientTlsHandler and instead relying on the setter in the SslContextBuilder, we can get the authentication flexibility that certain clients need for dealing with non-DNS identities, while preserving the safe defaults we currently have.

Activity

  1. kannanjgithub commented on Sep 10, 2025

    @kannanjgithub
    Contributor

    Thanks for the proposal Chris. Triaging this for the Next milestone.

  2. added this to the Next milestone on Sep 10, 2025
  3. ejona86 commented on Sep 10, 2025

    @ejona86
    Member

    Note: this might actually let us clean up some of the xds code, as XdsX509TrustManager has to set setEndpointIdentificationAlgorithm("") in a few places.

    public void checkServerTrusted(X509Certificate[] chain, String authType, SSLEngine sslEngine)
    throws CertificateException {
    SSLParameters sslParams = sslEngine.getSSLParameters();
    if (sslParams != null) {
    sslParams.setEndpointIdentificationAlgorithm("");
    sslEngine.setSSLParameters(sslParams);
    }
    chooseDelegate(chain).checkServerTrusted(chain, authType, sslEngine);
    verifySubjectAltNameInChain(chain);
    }

  4. added a commit that references this issue on Aug 27, 2026
    2858db2
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Metadata

Metadata

Assignees

No one assigned

    Type

    No type

    Projects

    No projects

      Relationships

      None yet

      Development

      No branches or pull requests

      Issue actions