From 8f63873ad6d87a8c0f28f5279097a4a4dc81ce2e Mon Sep 17 00:00:00 2001 From: Zeno Belli Date: Fri, 4 Sep 2026 13:37:21 +0200 Subject: [PATCH 1/5] chore: remove Taskfile and silence markdown warning --- CHANGELOG.md | 2 ++ Taskfile.yml | 61 ---------------------------------------------------- 2 files changed, 2 insertions(+), 61 deletions(-) delete mode 100644 Taskfile.yml diff --git a/CHANGELOG.md b/CHANGELOG.md index c920bcd..019d981 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -1,3 +1,5 @@ + + # https-wrench - changelog ## 0.15.1 (2026-09-03) diff --git a/Taskfile.yml b/Taskfile.yml deleted file mode 100644 index 8afc53a..0000000 --- a/Taskfile.yml +++ /dev/null @@ -1,61 +0,0 @@ -version: "3" - -tasks: - goreleaser:test:pkg: - internal: true - desc: Test a package installation - vars: - CONTAINER_NAME: "test-{{.Image}}-{{.Platform}}" - cmds: - - defer: docker rm -f {{.CONTAINER_NAME}} - - docker create --name {{.CONTAINER_NAME}} --platform linux/{{.Platform}} --workdir /tmp {{.Image}} sh -c 'ls -la /tmp && {{.Cmd}} && https-wrench --version' - - docker cp {{.TASKFILE_DIR}}/dist/. {{.CONTAINER_NAME}}:/tmp/ - - docker start -a {{.CONTAINER_NAME}} - - goreleaser:test:rpm: - desc: Tests rpm packages - vars: - RPM_INSTALL: "rpm --nodeps -ivh" - cmds: - - task: goreleaser:test:pkg - vars: - Platform: "amd64" - Image: fedora - Cmd: "{{.RPM_INSTALL}} https-wrench*_linux_amd64.rpm" - - task: goreleaser:test:pkg - vars: - Platform: "arm64" - Image: fedora - Cmd: "{{.RPM_INSTALL}} https-wrench*_linux_arm64.rpm" - - goreleaser:test:deb: - desc: Tests deb packages - vars: - DPKG_INSTALL: "dpkg --ignore-depends=git -i" - cmds: - - task: goreleaser:test:pkg - vars: - Platform: "amd64" - Image: ubuntu - Cmd: "{{.DPKG_INSTALL}} https-wrench*_linux_amd64.deb" - - task: goreleaser:test:pkg - vars: - Platform: "arm64" - Image: ubuntu - Cmd: "{{.DPKG_INSTALL}} https-wrench*_linux_arm64.deb" - - goreleaser:test:apk: - desc: Tests apk packages - vars: - APK_INSTALL: "apk add --allow-untrusted -U" - cmds: - - task: goreleaser:test:pkg - vars: - Platform: "amd64" - Image: alpine - Cmd: "{{.APK_INSTALL}} https-wrench*_linux_amd64.apk" - - task: goreleaser:test:pkg - vars: - Platform: "arm64" - Image: alpine - Cmd: "{{.APK_INSTALL}} https-wrench*_linux_arm64.apk" From cdb40f974a4a4877708485fe7fa2a4c1332475b4 Mon Sep 17 00:00:00 2001 From: Zeno Belli Date: Fri, 4 Sep 2026 13:40:59 +0200 Subject: [PATCH 2/5] refactor(certinfo): bind ephemeral port in custom httptest server to skip collisions in parallel tests List Go 1.27 ML-KEM hybrids in CurvePreferences so certinfo still negotiates them when GODEBUG would strip the defaults, and assert NegotiatedCurveID. Bind the test listener to an ephemeral port so parallel cases do not collide. Co-authored-by: Cursor --- internal/certinfo/certinfo_handlers.go | 12 ++ internal/certinfo/certinfo_handlers_test.go | 143 ++++++++++++-------- internal/certinfo/certinfo_test.go | 3 + internal/certinfo/main_test.go | 58 ++++---- 4 files changed, 133 insertions(+), 83 deletions(-) diff --git a/internal/certinfo/certinfo_handlers.go b/internal/certinfo/certinfo_handlers.go index b389032..b1c50c5 100644 --- a/internal/certinfo/certinfo_handlers.go +++ b/internal/certinfo/certinfo_handlers.go @@ -26,6 +26,17 @@ import ( "github.com/xenos76/https-wrench/internal/style" ) +// defaultCurvePreferences lists Go 1.27 TLS hybrids plus classical fallbacks. +// Explicit CurvePreferences keeps PQ on when GODEBUG=tlsmlkem=0 / tlssecpmlkem=0. +var defaultCurvePreferences = []tls.CurveID{ + tls.X25519MLKEM768, + tls.SecP256r1MLKEM768, + tls.SecP384r1MLKEM1024, + tls.X25519, + tls.CurveP256, + tls.CurveP384, +} + // PrintData prints all collected certificate and key information (local files and remote endpoints) // to the provided writer in a human-readable format. // @@ -202,6 +213,7 @@ func (c *Config) GetRemoteCerts(ctx context.Context) error { tlsConfig := &tls.Config{ RootCAs: c.CACertsPool, InsecureSkipVerify: c.TLSInsecure, + CurvePreferences: slices.Clone(defaultCurvePreferences), } verifyName := c.TLSServerName diff --git a/internal/certinfo/certinfo_handlers_test.go b/internal/certinfo/certinfo_handlers_test.go index 522241d..f16dade 100644 --- a/internal/certinfo/certinfo_handlers_test.go +++ b/internal/certinfo/certinfo_handlers_test.go @@ -3,9 +3,11 @@ package certinfo import ( "bytes" "context" + "crypto/tls" "crypto/x509" "crypto/x509/pkix" "math/big" + "net" "testing" "time" @@ -15,31 +17,26 @@ import ( //nolint:revive func TestCertinfo_GetRemoteCerts(t *testing.T) { tests := []struct { - desc string - srvCfg demoHTTPServerConfig - caCertFile string - insecure bool - expectSrvHost string - expectSrvPort string - expectError bool - expectMsg string + desc string + srvCfg demoHTTPServerConfig + caCertFile string + insecure bool + expectError bool + expectMsg string + wantCurveID string }{ { desc: "RSA Cert Success", srvCfg: demoHTTPServerConfig{ - serverAddr: "localhost:46301", serverName: "example.com", serverCertFile: RSASampleCertBundleFile, serverKeyFile: RSASampleCertKeyFile, }, - caCertFile: RSACaCertFile, - expectSrvHost: "localhost", - expectSrvPort: "46301", + caCertFile: RSACaCertFile, }, { desc: "Error Secure and No CA Cert", srvCfg: demoHTTPServerConfig{ - serverAddr: "localhost:46302", serverName: "example.com", serverCertFile: RSASampleCertFile, serverKeyFile: RSASampleCertKeyFile, @@ -53,75 +50,60 @@ func TestCertinfo_GetRemoteCerts(t *testing.T) { { desc: "Malformed Server Certificate", srvCfg: demoHTTPServerConfig{ - serverAddr: "localhost:46303", serverName: "example.com", serverCertFile: RSASamplePKCS8Certificate, serverKeyFile: RSASamplePKCS8PlaintextPrivateKey, }, - caCertFile: RSACaCertFile, - expectSrvHost: "localhost", + caCertFile: RSACaCertFile, //nolint:revive - expectSrvPort: "46303", - expectError: true, - expectMsg: "TLS handshake failed: tls: failed to verify certificate: x509: certificate relies on legacy Common Name field, use SANs instead", + expectError: true, + expectMsg: "TLS handshake failed: tls: failed to verify certificate: x509: certificate relies on legacy Common Name field, use SANs instead", }, { desc: "No CA Cert and Insecure", srvCfg: demoHTTPServerConfig{ - serverAddr: "localhost:46304", serverName: "example.com", serverCertFile: RSASampleCertFile, serverKeyFile: RSASampleCertKeyFile, }, - insecure: true, - expectSrvHost: "localhost", - expectSrvPort: "46304", - caCertFile: emptyString, + insecure: true, + caCertFile: emptyString, }, { desc: "Wrong CA Cert and Secure", srvCfg: demoHTTPServerConfig{ - serverAddr: "localhost:46305", serverName: "example.com", serverCertFile: RSASampleCertFile, serverKeyFile: RSASampleCertKeyFile, }, caCertFile: RSASamplePKCS8Certificate, //nolint:revive - expectSrvHost: "localhost", - expectSrvPort: "46305", - expectError: true, - expectMsg: "TLS handshake failed: tls: failed to verify certificate: x509: certificate signed by unknown authority", + expectError: true, + expectMsg: "TLS handshake failed: tls: failed to verify certificate: x509: certificate signed by unknown authority", }, { desc: "Wrong CA Cert and Insecure", srvCfg: demoHTTPServerConfig{ - serverAddr: "localhost:46306", serverName: "example.com", serverCertFile: RSASampleCertFile, serverKeyFile: RSASampleCertKeyFile, }, - caCertFile: RSASamplePKCS8Certificate, - insecure: true, - expectSrvHost: "localhost", - expectSrvPort: "46306", + caCertFile: RSASamplePKCS8Certificate, + insecure: true, }, { desc: "IPV6 Endpoint RSA Cert Success", srvCfg: demoHTTPServerConfig{ - serverAddr: "[::1]:46307", + listenHost: "::1", serverName: "example.com", serverCertFile: RSASampleCertFile, serverKeyFile: RSASampleCertKeyFile, }, - caCertFile: RSACaCertFile, - expectSrvHost: "::1", - expectSrvPort: "46307", + caCertFile: RSACaCertFile, }, { desc: "Error wrong ServerName", srvCfg: demoHTTPServerConfig{ - serverAddr: "localhost:46308", serverName: "example.co.uk", serverCertFile: RSASampleCertFile, //nolint:revive @@ -131,32 +113,74 @@ func TestCertinfo_GetRemoteCerts(t *testing.T) { expectError: true, expectMsg: "TLS handshake failed: tls: failed to verify certificate: x509: certificate is valid for example.com, example.net, example.de, not example.co.uk", }, + { + desc: "X25519MLKEM768 key exchange", + srvCfg: demoHTTPServerConfig{ + serverName: "example.com", + serverCertFile: RSASampleCertBundleFile, + serverKeyFile: RSASampleCertKeyFile, + tlsCurvePreferences: []tls.CurveID{tls.X25519MLKEM768}, + }, + caCertFile: RSACaCertFile, + wantCurveID: "X25519MLKEM768", + }, + { + desc: "SecP256r1MLKEM768 key exchange", + srvCfg: demoHTTPServerConfig{ + serverName: "example.com", + serverCertFile: RSASampleCertBundleFile, + serverKeyFile: RSASampleCertKeyFile, + tlsCurvePreferences: []tls.CurveID{tls.SecP256r1MLKEM768}, + }, + caCertFile: RSACaCertFile, + wantCurveID: "SecP256r1MLKEM768", + }, + { + desc: "SecP384r1MLKEM1024 key exchange", + srvCfg: demoHTTPServerConfig{ + serverName: "example.com", + serverCertFile: RSASampleCertBundleFile, + serverKeyFile: RSASampleCertKeyFile, + tlsCurvePreferences: []tls.CurveID{tls.SecP384r1MLKEM1024}, + }, + caCertFile: RSACaCertFile, + wantCurveID: "SecP384r1MLKEM1024", + }, } for _, tc := range tests { tt := tc t.Run(tt.desc, func(t *testing.T) { + t.Parallel() + ts, err := NewHTTPSTestServer(tt.srvCfg) require.NoError(t, err) + t.Cleanup(ts.Close) - defer ts.Close() + endpoint := testServerHostPort(ts) + host, port, err := net.SplitHostPort(endpoint) + require.NoError(t, err) cc, err := New() require.NoError(t, err) cc.SetTLSServerName(tt.srvCfg.serverName) cc.SetCaPoolFromFile(tt.caCertFile, inputReader) - cc.SetTLSEndpoint(context.Background(), tt.srvCfg.serverAddr) + cc.SetTLSEndpoint(t.Context(), endpoint) cc.SetTLSInsecure(tt.insecure) - err = cc.GetRemoteCerts(context.Background()) + err = cc.GetRemoteCerts(t.Context()) if !tt.expectError { require.NoError(t, err, "check error not expected") require.Equal(t, tt.srvCfg.serverName, cc.TLSServerName, "check TLSServerName") - require.Equal(t, tt.expectSrvHost, cc.TLSEndpointHost, "check TLSEndpointHost") - require.Equal(t, tt.expectSrvPort, cc.TLSEndpointPort, "check TLSEndpointPort") + require.Equal(t, host, cc.TLSEndpointHost, "check TLSEndpointHost") + require.Equal(t, port, cc.TLSEndpointPort, "check TLSEndpointPort") require.Equal(t, tt.insecure, cc.TLSInsecure, "check TLSInsecure") + if tt.wantCurveID != emptyString { + require.Equal(t, tt.wantCurveID, cc.NegotiatedCurveID, "check NegotiatedCurveID") + } + return } @@ -396,10 +420,8 @@ func TestCertinfo_PrintData(t *testing.T) { keyFile: RSASampleCertKeyFile, caCertFile: RSACaCertFile, keyCertMatch: true, - tlsEndpoint: "localhost:46401", tlsServerName: "example.com", srvCfg: demoHTTPServerConfig{ - serverAddr: "localhost:46401", serverName: "example.com", serverCertFile: RSASampleCertFile, serverKeyFile: RSASampleCertKeyFile, @@ -409,11 +431,9 @@ func TestCertinfo_PrintData(t *testing.T) { desc: "local key and remote TLS Endpoint, certs NOT validated", keyFile: RSASampleCertKeyFile, caCertFile: emptyString, - tlsEndpoint: "localhost:46402", tlsServerName: "example.com", //nolint:revive srvCfg: demoHTTPServerConfig{ - serverAddr: "localhost:46402", serverName: "example.com", serverCertFile: RSASampleCertFile, serverKeyFile: RSASampleCertKeyFile, @@ -429,25 +449,21 @@ func TestCertinfo_PrintData(t *testing.T) { keyFile: RSASampleCertKeyFile, caCertFile: emptyString, keyCertMatch: true, - tlsEndpoint: "localhost:46403", tlsInsecure: true, tlsServerName: "example.com", srvCfg: demoHTTPServerConfig{ - serverAddr: "localhost:46403", serverName: "example.com", serverCertFile: RSASampleCertFile, serverKeyFile: RSASampleCertKeyFile, }, }, { - desc: "local key and remote TLS Endpoint, missing TLS ServerName", - keyFile: RSASampleCertKeyFile, - caCertFile: RSACaCertFile, - tlsEndpoint: "localhost:46404", + desc: "local key and remote TLS Endpoint, missing TLS ServerName", + keyFile: RSASampleCertKeyFile, + caCertFile: RSACaCertFile, //nolint:revive tlsServerName: emptyString, srvCfg: demoHTTPServerConfig{ - serverAddr: "localhost:46404", serverName: "example.com", serverCertFile: RSASampleCertFile, //nolint:revive @@ -462,10 +478,8 @@ func TestCertinfo_PrintData(t *testing.T) { keyFile: ED25519SamplePlaintextPrivateKey, caCertFile: RSACaCertFile, keyCertMatch: false, - tlsEndpoint: "localhost:46405", tlsServerName: "example.com", srvCfg: demoHTTPServerConfig{ - serverAddr: "localhost:46405", serverName: "example.com", serverCertFile: RSASampleCertFile, serverKeyFile: RSASampleCertKeyFile, @@ -476,6 +490,7 @@ func TestCertinfo_PrintData(t *testing.T) { for _, tc := range tests { tt := tc t.Run("No errors test - "+tt.desc, func(t *testing.T) { + t.Parallel() runPrintDataSubtest(t, tt) }) } @@ -551,16 +566,24 @@ func runPrintDataSubtest(t *testing.T, tt printDataTestCase) { require.NoError(t, cc.SetCertsFromFile(tt.certFile, inputReader)) require.NoError(t, cc.SetCaPoolFromFile(tt.caCertFile, inputReader)) - if tt.tlsEndpoint != emptyString { + if tt.srvCfg.serverCertFile != emptyString { ts, errSrv := NewHTTPSTestServer(tt.srvCfg) require.NoError(t, errSrv) + t.Cleanup(ts.Close) - defer ts.Close() + tt.tlsEndpoint = testServerHostPort(ts) + if tt.tlsServerName == emptyString { + // Cert SANs include 127.0.0.1; dial by hostname so empty SNI still mismatches. + _, port, splitErr := net.SplitHostPort(tt.tlsEndpoint) + require.NoError(t, splitErr) + + tt.tlsEndpoint = net.JoinHostPort("localhost", port) + } cc.SetTLSServerName(tt.tlsServerName) cc.SetTLSInsecure(tt.tlsInsecure) - err = cc.SetTLSEndpoint(context.Background(), tt.tlsEndpoint) + err = cc.SetTLSEndpoint(t.Context(), tt.tlsEndpoint) if tt.expectCertsFetchErr { require.EqualError(t, err, tt.expectCertsFetcMsg) } else { diff --git a/internal/certinfo/certinfo_test.go b/internal/certinfo/certinfo_test.go index 362729a..8177619 100644 --- a/internal/certinfo/certinfo_test.go +++ b/internal/certinfo/certinfo_test.go @@ -552,6 +552,7 @@ func TestCertinfo_PrintTLSInfo_HappyPath(t *testing.T) { cc.TLSInfoRequested = true cc.NegotiatedProtocol = "TLS 1.3" cc.NegotiatedCipher = "TLS_AES_128_GCM_SHA256" + cc.NegotiatedCurveID = "X25519MLKEM768" cc.ProbedProtocols = map[string]bool{ "TLS 1.3": true, "TLS 1.2": true, @@ -585,6 +586,8 @@ func TestCertinfo_PrintTLSInfo_HappyPath(t *testing.T) { require.Contains(t, got, "Negotiated TLS Connection") require.Contains(t, got, "TLS 1.3") require.Contains(t, got, "TLS_AES_128_GCM_SHA256") + require.Contains(t, got, "Key Exchange") + require.Contains(t, got, "X25519MLKEM768") require.Contains(t, got, "Protocol Support Scan") require.Contains(t, got, "Cipher Suite Scan") require.Contains(t, got, "TLS_ECDHE_RSA_WITH_AES_128_CBC_SHA256") diff --git a/internal/certinfo/main_test.go b/internal/certinfo/main_test.go index 818a34f..630e74a 100644 --- a/internal/certinfo/main_test.go +++ b/internal/certinfo/main_test.go @@ -32,13 +32,14 @@ type ( } demoHTTPServerConfig struct { - serverAddr string - proxyprotoEnabled bool - serverName string - tlsCipherSuites []uint16 - tlsMaxVersion uint16 - serverCertFile string - serverKeyFile string + listenHost string + proxyprotoEnabled bool + serverName string + tlsCipherSuites []uint16 + tlsCurvePreferences []tls.CurveID + tlsMaxVersion uint16 + serverCertFile string + serverKeyFile string } MockErrReader struct{} @@ -374,6 +375,16 @@ func RSAPrivateKeyToPEM(key *rsa.PrivateKey) []byte { return keyPEM } +func testServerHostPort(ts *httptest.Server) string { + return ts.Listener.Addr().String() +} + +// NewHTTPSTestServer starts an httptest TLS server configured by cfg. +// Cipher suites default to the TLS 1.3 AEADs, CurvePreferences to the Go 1.27 +// PQ hybrids plus classical fallbacks, and MaxVersion to TLS 1.3. Non-empty +// cfg.tlsCipherSuites, cfg.tlsCurvePreferences, or a non-zero cfg.tlsMaxVersion +// override those defaults. Optional cfg.listenHost and cfg.proxyprotoEnabled +// replace the listener. The caller must Close the returned server. func NewHTTPSTestServer(cfg demoHTTPServerConfig) (*httptest.Server, error) { handler := http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) { fmt.Fprint(w, "DemoHTTPSServer Handler - client output\n") @@ -385,27 +396,21 @@ func NewHTTPSTestServer(cfg demoHTTPServerConfig) (*httptest.Server, error) { ts := httptest.NewUnstartedServer(handler) ts.EnableHTTP2 = true - if cfg.serverAddr != emptyString && !cfg.proxyprotoEnabled { - listener, err := net.Listen("tcp", cfg.serverAddr) + if cfg.listenHost != emptyString { + ln, err := net.Listen("tcp", net.JoinHostPort(cfg.listenHost, "0")) if err != nil { return nil, fmt.Errorf("error creating listener: %w", err) } - ts.Listener = listener + _ = ts.Listener.Close() + ts.Listener = ln } - if cfg.serverAddr != emptyString && cfg.proxyprotoEnabled { - ln, err := net.Listen("tcp", cfg.serverAddr) - if err != nil { - return nil, fmt.Errorf("error creating proxyproto enabled listener: %w", err) - } - - proxyListener := &proxyproto.Listener{ - Listener: ln, + if cfg.proxyprotoEnabled { + ts.Listener = &proxyproto.Listener{ + Listener: ts.Listener, ReadHeaderTimeout: 10 * time.Second, } - - ts.Listener = proxyListener } cert, err := tls.LoadX509KeyPair( @@ -428,6 +433,12 @@ func NewHTTPSTestServer(cfg demoHTTPServerConfig) (*httptest.Server, error) { tlsCipherSuites = cfg.tlsCipherSuites } + tlsCurvePreferences := defaultCurvePreferences + + if len(cfg.tlsCurvePreferences) > 0 { + tlsCurvePreferences = cfg.tlsCurvePreferences + } + // Set default TLS MaxVersion to 1.3 var tlsMaxVersion uint16 = tls.VersionTLS13 @@ -436,9 +447,10 @@ func NewHTTPSTestServer(cfg demoHTTPServerConfig) (*httptest.Server, error) { } ts.TLS = &tls.Config{ - Certificates: []tls.Certificate{cert}, - CipherSuites: tlsCipherSuites, - MaxVersion: tlsMaxVersion, + Certificates: []tls.Certificate{cert}, + CipherSuites: tlsCipherSuites, + CurvePreferences: tlsCurvePreferences, + MaxVersion: tlsMaxVersion, } ts.StartTLS() From b4ab1b9987abb2b8cf6e8f70c5ba609edd1f15a4 Mon Sep 17 00:00:00 2001 From: Zeno Belli Date: Fri, 4 Sep 2026 14:20:13 +0200 Subject: [PATCH 3/5] ci: use Go 1.27.1 --- .github/workflows/codeChecks.yml | 8 ++++---- .github/workflows/release.yml | 2 +- go.mod | 2 +- 3 files changed, 6 insertions(+), 6 deletions(-) diff --git a/.github/workflows/codeChecks.yml b/.github/workflows/codeChecks.yml index 1e67962..1681afb 100644 --- a/.github/workflows/codeChecks.yml +++ b/.github/workflows/codeChecks.yml @@ -26,7 +26,7 @@ jobs: strategy: max-parallel: 2 matrix: - go-version: ["1.27.0"] + go-version: ["1.27.1"] steps: - name: Checkout uses: actions/checkout@de0fac2e4500dabe0009e67214ff5f5447ce83dd # v6.0.2 @@ -47,7 +47,7 @@ jobs: strategy: max-parallel: 2 matrix: - go-version: ["1.27.0"] + go-version: ["1.27.1"] steps: - name: Checkout @@ -74,7 +74,7 @@ jobs: strategy: max-parallel: 2 matrix: - go-version: ["1.27.0"] + go-version: ["1.27.1"] steps: - name: Checkout @@ -103,7 +103,7 @@ jobs: - uses: actions/checkout@93cb6efe18208431cddfb8368fd83d5badbf9bfd # v5.0.1 - uses: actions/setup-go@4a3601121dd01d1626a1e23e37211e3254c1c06c # v6.4.0 with: - go-version: "1.27.0" + go-version: "1.27.1" - name: generate test coverage run: go test ./... -coverprofile=./cover.out -covermode=atomic -coverpkg=./... diff --git a/.github/workflows/release.yml b/.github/workflows/release.yml index 1d289a2..126717d 100644 --- a/.github/workflows/release.yml +++ b/.github/workflows/release.yml @@ -12,7 +12,7 @@ permissions: env: CGO_ENABLED: 0 DOCKER_CLI_EXPERIMENTAL: "enabled" - GO_VERSION: "1.27.0" + GO_VERSION: "1.27.1" jobs: code-checks: diff --git a/go.mod b/go.mod index ca37540..4007ccf 100644 --- a/go.mod +++ b/go.mod @@ -1,6 +1,6 @@ module github.com/xenos76/https-wrench -go 1.27.0 +go 1.27.1 require ( github.com/MicahParks/jwkset v0.11.3 From 2e932c2fb68e2d5856cd587561cc538c250450bc Mon Sep 17 00:00:00 2001 From: Zeno Belli Date: Fri, 4 Sep 2026 14:21:07 +0200 Subject: [PATCH 4/5] test(certinfo): set TLS insecure before endpoint fetch GetRemoteCerts tests now apply SetTLSInsecure before SetTLSEndpoint so the endpoint certificate retrieval uses the intended verification mode. --- internal/certinfo/certinfo_handlers_test.go | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/internal/certinfo/certinfo_handlers_test.go b/internal/certinfo/certinfo_handlers_test.go index f16dade..4eb9ed9 100644 --- a/internal/certinfo/certinfo_handlers_test.go +++ b/internal/certinfo/certinfo_handlers_test.go @@ -166,8 +166,8 @@ func TestCertinfo_GetRemoteCerts(t *testing.T) { cc.SetTLSServerName(tt.srvCfg.serverName) cc.SetCaPoolFromFile(tt.caCertFile, inputReader) - cc.SetTLSEndpoint(t.Context(), endpoint) cc.SetTLSInsecure(tt.insecure) + cc.SetTLSEndpoint(t.Context(), endpoint) err = cc.GetRemoteCerts(t.Context()) if !tt.expectError { From 4787708823faa8588f6e6ab7f8bbccc86e57e7af Mon Sep 17 00:00:00 2001 From: Zeno Belli Date: Fri, 4 Sep 2026 14:21:19 +0200 Subject: [PATCH 5/5] chore: update changelog --- CHANGELOG.md | 10 ++++++++++ 1 file changed, 10 insertions(+) diff --git a/CHANGELOG.md b/CHANGELOG.md index 019d981..05064a3 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -2,6 +2,16 @@ # https-wrench - changelog +## Unreleased + +### CI + + switch to Go 1.27.1 + +### Tests + + Certinfo: GetRemoteCerts tests apply SetTLSInsecure before SetTLSEndpoint so endpoint certificate retrieval uses the intended TLS verification mode. + ## 0.15.1 (2026-09-03) ### Feat