Sylwester Lachiewicz created THRIFT-6275:
--------------------------------------------

             Summary: Go cross-test client presents no client certificate, and 
Go cannot load client_v3.crt
                 Key: THRIFT-6275
                 URL: https://issues.apache.org/jira/browse/THRIFT-6275
             Project: Thrift
          Issue Type: Bug
          Components: Go - Library, Test Suite
            Reporter: Sylwester Lachiewicz


Every {{py-go_*-ip-ssl}} row of the cross-test matrix, 18 in all, has been 
listed in 
[test/known_failures_Linux.json|https://github.com/apache/thrift/blob/master/test/known_failures_Linux.json]
 since THRIFT-847 in 2015. Re-running them on a fork branch with the entries 
removed shows two defects on the Go client side that stack, so fixing either 
alone changes nothing.

h2. 1. The Go cross-test client presents no client certificate

The TLS configuration in 
[test/go/src/common/client.go|https://github.com/apache/thrift/blob/master/test/go/src/common/client.go#L46]
 sets only {{InsecureSkipVerify}}. The Python test server requires a client 
certificate 
([test/py/TestServer.py:390|https://github.com/apache/thrift/blob/master/test/py/TestServer.py#L390],
 {{cert_reqs=CERT_REQUIRED}}), so every socket transport over SSL fails at the 
handshake:

{noformat}
Unexpected error in TestVoid() call: remote error: tls: certificate required
{noformat}

The http-ip-ssl rows pass only because the Python HTTP server does not ask for 
one, and rb-go passes because the Ruby server uses {{VERIFY_PEER}} without 
failing on an absent certificate. Every other cross-test client that presents a 
certificate sends {{client_v3.crt}}.

h2. 2. Go cannot load client_v3.crt

{{test/keys/client_v3.crt}} lists the alternative names 127.0.0.1, ::1, 
::ffff:127.0.0.1 and localhost. Go's x509 parser rejects any certificate 
carrying an IPv4-mapped IPv6 address as a SAN, and the TLS client will not send 
a certificate it cannot parse:

{noformat}
x509: SAN iPAddress contains IPv4-mapped IPv6 address
{noformat}

Reproduced with Go 1.27.1; CI runs 1.26 and 1.27. THRIFT-3660 added that entry 
in 2016 so the Python server's peer-address check would match a dual-stack 
peer. Since THRIFT-6201 the Python matcher reduces {{::ffff:127.0.0.1}} to 
{{127.0.0.1}} before comparing, so the entry is redundant.

A related documentation defect: the recipe in 
[test/keys/README.md|https://github.com/apache/thrift/blob/master/test/keys/README.md]
 says to sign {{client_v3.crt}} with {{CA.pem}} and {{server.key}}, but the 
certificate shipped since the 2022 regeneration is self-signed with 
{{client_v3.key}}. A certificate made from the recipe is rejected by the Python 
server with {{unable to get local issuer certificate}}.

h2. Proposed fix

* Give the Go test client a {{--certPath}} flag like the server's and load 
{{client_v3.crt}} and {{client_v3.key}} into its TLS configuration when 
{{--ssl}} is set; pass the flag in {{test/tests.json}}.
* Regenerate {{client_v3.crt}} self-signed with the same key, the same 
distinguished name and extensions, and the alternative names 127.0.0.1, ::1 and 
localhost. Regenerate {{lib/java/src/crossTest/resources/.clientkeystore}} from 
it, as the README describes.
* Correct the README recipe to produce what is shipped.
* Remove the 18 {{py-go_*-ip-ssl}} entries from the known failures.

With those changes, all twelve py-go SSL combinations (binary, compact, json 
and header over buffered, framed and zlib) pass locally against a Python server 
built from master. The cross-test run behind this analysis is recorded on 
THRIFT-5809; THRIFT-4502 tracks the known-failures cleanup in general.

_This issue was created with AI assistance._



--
This message was sent by Atlassian Jira
(v8.20.10#820010)

Reply via email to