javasslgrpcgrpc-java

gRPC client failing to connect with server with SSL/TLS


I am trying to connect to gRPC server which has TLS enabled but doesn't require a client certificate. I have used many combinations using NettyChannelBuilder and ManagedChannelBuilder.

NettyChannelBuilder.forTarget("host:443")
                    .useTransportSecurity()
                    .keepAliveTime(30, TimeUnit.SECONDS)
                    .keepAliveTimeout(5, TimeUnit.SECONDS)
                    .negotiationType(NegotiationType.TLS)
                    .enableRetry()
                    .build();

Error is

io.grpc.StatusRuntimeException: UNAVAILABLE: io exception

Underlying exception is

Caused by: sun.security.validator.ValidatorException: PKIX path building failed: sun.security.provider.certpath.SunCertPathBuilderException: unable to find valid certification path to requested target

What am I doing wrong?


Solution

  • unable to find valid certification path to requested target

    The server's certificate is not trusted. You should get a CA to issue a certificate for the server. If it is already a valid cert, make sure to provide the "certificate chain" when configuring the server, not just the bare server certificate.

    If you didn't intend to use a typical "browser-trusted CA," you can sign the certificate with your own CA and use that CA's certificate as a trust source:

    ChannelCredentials certs = TlsChannelCredentials.newBuilder()
        // Could also be a server's self-signed cert
        .trustManager(new File("path/to/ca.pem"))
        .build();
    NettyChannelBuilder.forTarget("host:443", certs)
        .keepAliveTime(30, TimeUnit.SECONDS)
        .keepAliveTimeout(5, TimeUnit.SECONDS)
        .build();
    

    There are many sites and scripts that describe how to make your own CA and sign server certificates, if that is what you end up wanting. For reference, this is the process for gRPC's tests.