Hello!
I have just noticed, that below code snippet works only if Let’s Encrypt’s certificate chain is RSA (host) ← RSA (LE) ←RSA (ISRG Root X1) (https://ziglang.org ). If the chain is EC ← EC ← RSA (https://www.ar-fi.com ), it fails:
zig build run
error: TlsInitializationFailed
/home/ws/tools/zig/build_release_15_3/stage3/lib/zig/std/crypto/tls/Client.zig:791:45: 0x11d29bf in init (zig_snip)
.certificate => return error.TlsCertificateNotVerified,
^
/home/ws/tools/zig/build_release_15_3/stage3/lib/zig/std/http/Client.zig:342:25: 0x112b1ab in create (zig_snip)
) catch return error.TlsInitializationFailed,
^
/home/ws/tools/zig/build_release_15_3/stage3/lib/zig/std/http/Client.zig:1450:24: 0x111b326 in connectTcpOptions (zig_snip)
const tc = try Connection.Tls.create(client, proxied_host, proxied_port, stream);
^
/home/ws/tools/zig/build_release_15_3/stage3/lib/zig/std/http/Client.zig:1408:5: 0x111b5b3 in connectTcp (zig_snip)
return connectTcpOptions(client, .{ .host = host, .port = port, .protocol = protocol });
^
/home/ws/tools/zig/build_release_15_3/stage3/lib/zig/std/http/Client.zig:1583:14: 0x110e3d8 in connect (zig_snip)
} orelse return client.connectTcp(host, port, protocol);
^
/home/ws/tools/zig/build_release_15_3/stage3/lib/zig/std/http/Client.zig:1699:18: 0x1108db1 in request (zig_snip)
break :c try client.connect(host_name, uriPort(uri, protocol), protocol);
^
/home/ws/tools/zig/build_release_15_3/stage3/lib/zig/std/http/Client.zig:1789:15: 0x1103fe4 in fetch (zig_snip)
var req = try request(client, method, uri, .{
^
/home/ws/p/zig-snip/src/main.zig:20:22: 0x110379e in main (zig_snip)
const response = try client.fetch(.{
^
run
± run exe zig_snip failure
error: the following command exited with error code 1:
/home/ws/p/zig-snip/zig-out/bin/zig_snip
Build Summary: 3/5 steps succeeded; 1 failed
run transitive failure
± run exe zig_snip failure
error: the following build command failed with exit code 1:
.zig-cache/o/38297ce60136dea2b2c5c20231adfba8/build /home/ws/tools/zig/build_release_15_3/stage3/bin/zig /home/ws/tools/zig/build_release_15_3/stage3/lib/zig /home/ws/p/zig-snip .zig-cache /home/ws/.cache/zig --seed 0xed0127a4 -Z0ab0dc7b672c0d39 run
Compilation exited abnormally with code 1 at Thu Dec 18 13:59:05, duration 0.72 s
triggering code:
const std = @import(“std”);
const http = std.http;
pub fn main() !void {
var gpa = std.heap.GeneralPurposeAllocator(.{}){};
const allocator = gpa.allocator();
var client = http.Client{ .allocator = allocator };
defer client.deinit();
// const url = "https://ziglang.org";
const url = "https://www.ar-fi.com";
const file = try (try std.fs.openDirAbsolute("/tmp", .{})).createFile("dl.stuff", .{ .mode = 0o777, .truncate = true });
defer file.close();
var wr_buf: [64]u8 = undefined;
var writer = file.writer(&wr_buf);
const response = try client.fetch(.{
.location = .{ .url = url },
.redirect_behavior = .not_allowed,
.method = .GET,
.response_writer = &writer.interface,
});
std.debug.assert(response.status == .ok);
try writer.interface.flush();
}
Is this a well known issue, or something new?
There are a few issues around certificates:
opened 08:03PM - 16 Oct 25 UTC
bug
### Zig Version
0.15.1
### Steps to Reproduce and Observed Behavior
I found o… ut zig has issue with TLS verification.
For example `debuginfod.elfutils.org` returns 2 times same `Certificate` in chain.
Repro:
```zig
test "debuginfod.elfutils.org" {
const allocator = std.testing.allocator;
var client = std.http.Client{
.allocator = allocator,
};
defer client.deinit();
const result = try client.fetch(.{
.location = .{ .url = "https://debuginfod.elfutils.org/buildid/11dc8cd87b01714abd2e9d9a2462641f20d5df9b/debuginfo" },
});
try std.testing.expect(result.status == .ok);
}
```
output:
```console
$ zig build test
test
└─ run test 8/9 passed, 1 failed
/truncate/lib/zig/std/crypto/Certificate.zig:257:13: 0x102b6ab6f in verify (test)
return error.CertificateIssuerMismatch;
^
/truncate/lib/zig/std/crypto/tls/Client.zig:639:33: 0x102b3eeeb in init (test)
try prev_cert.verify(subject, now_sec);
^
/truncate/lib/zig/std/http/Client.zig:342:25: 0x102a5792b in create (test)
) catch return error.TlsInitializationFailed,
^
/truncate/lib/zig/std/http/Client.zig:1450:24: 0x102a4789b in connectTcpOptions (test)
const tc = try Connection.Tls.create(client, proxied_host, proxied_port, stream);
^
/truncate/lib/zig/std/http/Client.zig:1408:5: 0x102a47ad3 in connectTcp (test)
return connectTcpOptions(client, .{ .host = host, .port = port, .protocol = protocol });
^
/truncate/lib/zig/std/http/Client.zig:1583:14: 0x102a3b7cf in connect (test)
} orelse return client.connectTcp(host, port, protocol);
^
/truncate/lib/zig/std/http/Client.zig:1699:18: 0x102a32bc3 in request (test)
break :c try client.connect(host_name, uriPort(uri, protocol), protocol);
^
/truncate/lib/zig/std/http/Client.zig:1789:15: 0x102c87407 in fetch (test)
var req = try request(client, method, uri, .{
^
/truncate/src/helpers.zig:130:20: 0x102c8704b in test.debuginfod.elfutils.org (test)
const result = try client.fetch(.{
^
```
openssl info:
```console
$ openssl s_client -connect debuginfod.elfutils.org:443 -servername debuginfod.elfutils.org -showcerts
CONNECTED(00000005)
depth=2 C = US, O = Internet Security Research Group, CN = ISRG Root X1
verify return:1
depth=1 C = US, O = Let's Encrypt, CN = R11
verify return:1
depth=0 CN = debuginfod.elfutils.org
verify return:1
write W BLOCK
---
Certificate chain
0 s:/CN=debuginfod.elfutils.org
i:/C=US/O=Let's Encrypt/CN=R11
-----BEGIN CERTIFICATE-----
MIIFCjCCA/KgAwIBAgISBSod53bZfZDrsCV7agMwyx2XMA0GCSqGSIb3DQEBCwUA
MDMxCzAJBgNVBAYTAlVTMRYwFAYDVQQKEw1MZXQncyBFbmNyeXB0MQwwCgYDVQQD
EwNSMTEwHhcNMjUwODIwMDMxMTUzWhcNMjUxMTE4MDMxMTUyWjAiMSAwHgYDVQQD
ExdkZWJ1Z2luZm9kLmVsZnV0aWxzLm9yZzCCASIwDQYJKoZIhvcNAQEBBQADggEP
ADCCAQoCggEBAKjcvI4uh+V96MZ+sjdEOY7A8zCuEKr8u9HJlRLCTEVEvMQQPUrv
OzEssbd6EFtk/gX7J3Bpda97Rzbk9uEUuocZ/ST0uMZZGjwSq+9mrua2/l20UeVg
RYrA+pznT8ERIn8UlXF4+P0gKJOZrAPoxOI083C+tQp64N4IsBw6n2qAb1SnqLpF
t2hTM5ShqybRos1MJ9C1YnFTVUkQNHJd7fomIGKcI+9ELbIULAoZznrbfKiErXNz
R3M0eOm7LRZ6pCo6kyWzhWSc9bkzc1bwqG4uSUkWDl7I6/nmPZQA1fPtR0frvaKX
C0a2r+HO9T32eJHzhV1sTXyj+DZ7+jPQx3sCAwEAAaOCAicwggIjMA4GA1UdDwEB
/wQEAwIFoDAdBgNVHSUEFjAUBggrBgEFBQcDAQYIKwYBBQUHAwIwDAYDVR0TAQH/
BAIwADAdBgNVHQ4EFgQUum9ZgDvQuIXYODWCQPLEr0PX7vIwHwYDVR0jBBgwFoAU
xc9GpOr0w8B6bJXELbBeki8m47kwMwYIKwYBBQUHAQEEJzAlMCMGCCsGAQUFBzAC
hhdodHRwOi8vcjExLmkubGVuY3Iub3JnLzAiBgNVHREEGzAZghdkZWJ1Z2luZm9k
LmVsZnV0aWxzLm9yZzATBgNVHSAEDDAKMAgGBmeBDAECATAuBgNVHR8EJzAlMCOg
IaAfhh1odHRwOi8vcjExLmMubGVuY3Iub3JnLzI0LmNybDCCAQQGCisGAQQB1nkC
BAIEgfUEgfIA8AB2AMz7D2qFcQll/pWbU87psnwi6YVcDZeNtql+VMD+TA2wAAAB
mMWrvjwAAAQDAEcwRQIhAK8OTQKfhmpp8xhLgzNvM1TvRWb5c7sxgy8SAORq9yQm
AiAOq/t7dYo8ri8FhIghoPtAqEOi4lao3tlk156vwLYZyQB2AKRCxQZJYGFUjw/U
6pz7ei0mRU2HqX8v30VZ9idPOoRUAAABmMWrvjQAAAQDAEcwRQIgCvX8vPiFf0uY
M+PYeLA8APx7GFTulsgEytBwCVg+UZkCIQDamhbias7GZ8JvqLCWmqtuiAkRBJ8B
kr67mdSKj4WMMTANBgkqhkiG9w0BAQsFAAOCAQEAICbBd9Bmctznm0QcKPZ981al
L1E/AMNuzMxheVoRYZuq8cb3xyFiYILyle31I9XfQy/OP7D6HK+qDgTlWSJ2/Y/x
EXSd3dQpYEkGYbWJ9VG3Cf1TImfa2bwxkQ4vTW7yePi+VDXi+ydXaGZ1+KxrMq++
oCcb24NJjk4DY2uJC1tXi+064trb3jm5gCqjfDRon3YePkN+YWCFSDMe1phhWQcE
XNS3B1HcrzO+rr7MrnPWg03DO8cO9eHQG82qfx7Ydpc3ojnxWcGsVsIwgd7glHsR
1bkU5nNi+aAJSUJLcttvCOery+6Cli/oTgsNLZ0SCmckSqHGgBbH20GtlMk0oQ==
-----END CERTIFICATE-----
1 s:/CN=debuginfod.elfutils.org
i:/C=US/O=Let's Encrypt/CN=R11
-----BEGIN CERTIFICATE-----
MIIFCjCCA/KgAwIBAgISBSod53bZfZDrsCV7agMwyx2XMA0GCSqGSIb3DQEBCwUA
MDMxCzAJBgNVBAYTAlVTMRYwFAYDVQQKEw1MZXQncyBFbmNyeXB0MQwwCgYDVQQD
EwNSMTEwHhcNMjUwODIwMDMxMTUzWhcNMjUxMTE4MDMxMTUyWjAiMSAwHgYDVQQD
ExdkZWJ1Z2luZm9kLmVsZnV0aWxzLm9yZzCCASIwDQYJKoZIhvcNAQEBBQADggEP
ADCCAQoCggEBAKjcvI4uh+V96MZ+sjdEOY7A8zCuEKr8u9HJlRLCTEVEvMQQPUrv
OzEssbd6EFtk/gX7J3Bpda97Rzbk9uEUuocZ/ST0uMZZGjwSq+9mrua2/l20UeVg
RYrA+pznT8ERIn8UlXF4+P0gKJOZrAPoxOI083C+tQp64N4IsBw6n2qAb1SnqLpF
t2hTM5ShqybRos1MJ9C1YnFTVUkQNHJd7fomIGKcI+9ELbIULAoZznrbfKiErXNz
R3M0eOm7LRZ6pCo6kyWzhWSc9bkzc1bwqG4uSUkWDl7I6/nmPZQA1fPtR0frvaKX
C0a2r+HO9T32eJHzhV1sTXyj+DZ7+jPQx3sCAwEAAaOCAicwggIjMA4GA1UdDwEB
/wQEAwIFoDAdBgNVHSUEFjAUBggrBgEFBQcDAQYIKwYBBQUHAwIwDAYDVR0TAQH/
BAIwADAdBgNVHQ4EFgQUum9ZgDvQuIXYODWCQPLEr0PX7vIwHwYDVR0jBBgwFoAU
xc9GpOr0w8B6bJXELbBeki8m47kwMwYIKwYBBQUHAQEEJzAlMCMGCCsGAQUFBzAC
hhdodHRwOi8vcjExLmkubGVuY3Iub3JnLzAiBgNVHREEGzAZghdkZWJ1Z2luZm9k
LmVsZnV0aWxzLm9yZzATBgNVHSAEDDAKMAgGBmeBDAECATAuBgNVHR8EJzAlMCOg
IaAfhh1odHRwOi8vcjExLmMubGVuY3Iub3JnLzI0LmNybDCCAQQGCisGAQQB1nkC
BAIEgfUEgfIA8AB2AMz7D2qFcQll/pWbU87psnwi6YVcDZeNtql+VMD+TA2wAAAB
mMWrvjwAAAQDAEcwRQIhAK8OTQKfhmpp8xhLgzNvM1TvRWb5c7sxgy8SAORq9yQm
AiAOq/t7dYo8ri8FhIghoPtAqEOi4lao3tlk156vwLYZyQB2AKRCxQZJYGFUjw/U
6pz7ei0mRU2HqX8v30VZ9idPOoRUAAABmMWrvjQAAAQDAEcwRQIgCvX8vPiFf0uY
M+PYeLA8APx7GFTulsgEytBwCVg+UZkCIQDamhbias7GZ8JvqLCWmqtuiAkRBJ8B
kr67mdSKj4WMMTANBgkqhkiG9w0BAQsFAAOCAQEAICbBd9Bmctznm0QcKPZ981al
L1E/AMNuzMxheVoRYZuq8cb3xyFiYILyle31I9XfQy/OP7D6HK+qDgTlWSJ2/Y/x
EXSd3dQpYEkGYbWJ9VG3Cf1TImfa2bwxkQ4vTW7yePi+VDXi+ydXaGZ1+KxrMq++
oCcb24NJjk4DY2uJC1tXi+064trb3jm5gCqjfDRon3YePkN+YWCFSDMe1phhWQcE
XNS3B1HcrzO+rr7MrnPWg03DO8cO9eHQG82qfx7Ydpc3ojnxWcGsVsIwgd7glHsR
1bkU5nNi+aAJSUJLcttvCOery+6Cli/oTgsNLZ0SCmckSqHGgBbH20GtlMk0oQ==
-----END CERTIFICATE-----
2 s:/C=US/O=Let's Encrypt/CN=R11
i:/C=US/O=Internet Security Research Group/CN=ISRG Root X1
-----BEGIN CERTIFICATE-----
MIIFBjCCAu6gAwIBAgIRAIp9PhPWLzDvI4a9KQdrNPgwDQYJKoZIhvcNAQELBQAw
TzELMAkGA1UEBhMCVVMxKTAnBgNVBAoTIEludGVybmV0IFNlY3VyaXR5IFJlc2Vh
cmNoIEdyb3VwMRUwEwYDVQQDEwxJU1JHIFJvb3QgWDEwHhcNMjQwMzEzMDAwMDAw
WhcNMjcwMzEyMjM1OTU5WjAzMQswCQYDVQQGEwJVUzEWMBQGA1UEChMNTGV0J3Mg
RW5jcnlwdDEMMAoGA1UEAxMDUjExMIIBIjANBgkqhkiG9w0BAQEFAAOCAQ8AMIIB
CgKCAQEAuoe8XBsAOcvKCs3UZxD5ATylTqVhyybKUvsVAbe5KPUoHu0nsyQYOWcJ
DAjs4DqwO3cOvfPlOVRBDE6uQdaZdN5R2+97/1i9qLcT9t4x1fJyyXJqC4N0lZxG
AGQUmfOx2SLZzaiSqhwmej/+71gFewiVgdtxD4774zEJuwm+UE1fj5F2PVqdnoPy
6cRms+EGZkNIGIBloDcYmpuEMpexsr3E+BUAnSeI++JjF5ZsmydnS8TbKF5pwnnw
SVzgJFDhxLyhBax7QG0AtMJBP6dYuC/FXJuluwme8f7rsIU5/agK70XEeOtlKsLP
Xzze41xNG/cLJyuqC0J3U095ah2H2QIDAQABo4H4MIH1MA4GA1UdDwEB/wQEAwIB
hjAdBgNVHSUEFjAUBggrBgEFBQcDAgYIKwYBBQUHAwEwEgYDVR0TAQH/BAgwBgEB
/wIBADAdBgNVHQ4EFgQUxc9GpOr0w8B6bJXELbBeki8m47kwHwYDVR0jBBgwFoAU
ebRZ5nu25eQBc4AIiMgaWPbpm24wMgYIKwYBBQUHAQEEJjAkMCIGCCsGAQUFBzAC
hhZodHRwOi8veDEuaS5sZW5jci5vcmcvMBMGA1UdIAQMMAowCAYGZ4EMAQIBMCcG
A1UdHwQgMB4wHKAaoBiGFmh0dHA6Ly94MS5jLmxlbmNyLm9yZy8wDQYJKoZIhvcN
AQELBQADggIBAE7iiV0KAxyQOND1H/lxXPjDj7I3iHpvsCUf7b632IYGjukJhM1y
v4Hz/MrPU0jtvfZpQtSlET41yBOykh0FX+ou1Nj4ScOt9ZmWnO8m2OG0JAtIIE38
01S0qcYhyOE2G/93ZCkXufBL713qzXnQv5C/viOykNpKqUgxdKlEC+Hi9i2DcaR1
e9KUwQUZRhy5j/PEdEglKg3l9dtD4tuTm7kZtB8v32oOjzHTYw+7KdzdZiw/sBtn
UfhBPORNuay4pJxmY/WrhSMdzFO2q3Gu3MUBcdo27goYKjL9CTF8j/Zz55yctUoV
aneCWs/ajUX+HypkBTA+c8LGDLnWO2NKq0YD/pnARkAnYGPfUDoHR9gVSp/qRx+Z
WghiDLZsMwhN1zjtSC0uBWiugF3vTNzYIEFfaPG7Ws3jDrAMMYebQ95JQ+HIBD/R
PBuHRTBpqKlyDnkSHDHYPiNX3adPoPAcgdF3H2/W0rmoswMWgTlLn1Wu0mrks7/q
pdWfS6PJ1jty80r2VKsM/Dj3YIDfbjXKdaFU5C+8bhfJGqU3taKauuz0wHVGT3eo
6FlWkWYtbt4pgdamlwVeZEW+LM7qZEJEsMNPrfC03APKmZsJgpWCDWOKZvkZcvjV
uYkQ4omYCTX5ohy+knMjdOmdH9c7SpqEWBDC86fiNex+O0XOMEZSa8DA
-----END CERTIFICATE-----
---
Server certificate
subject=/CN=debuginfod.elfutils.org
issuer=/C=US/O=Let's Encrypt/CN=R11
---
No client certificate CA names sent
Server Temp Key: ECDH, X25519, 253 bits
---
SSL handshake has read 4432 bytes and written 383 bytes
---
New, TLSv1/SSLv3, Cipher is AEAD-CHACHA20-POLY1305-SHA256
Server public key is 2048 bit
Secure Renegotiation IS NOT supported
Compression: NONE
Expansion: NONE
No ALPN negotiated
SSL-Session:
Protocol : TLSv1.3
Cipher : AEAD-CHACHA20-POLY1305-SHA256
Session-ID:
Session-ID-ctx:
Master-Key:
Start Time: 1760644075
Timeout : 7200 (sec)
Verify return code: 0 (ok)
---
read R BLOCK
read R BLOCK
closed
```
### Expected Behavior
https request should work fine without TLS error. Every other client work fine for that domain.
opened 10:42PM - 08 Oct 24 UTC
bug
standard library
### Zig Version
0.14.0-dev.1820+ea527f7a8
### Steps to Reproduce and Observed … Behavior
```
_ = try std.http.Client.fetch(&client, .{
.location = .{
.url = "http://wttr.in/pdx?format=%t",
},
.response_storage = std.http.Client.FetchOptions.ResponseStorage{
.dynamic = &r,
},
});
```
leads to:
```
error: TlsInitializationFailed
/home/michael/opt/zig-linux-x86_64-0.14.0-dev.1820+ea527f7a8/lib/std/crypto/tls/Client.zig:568:49: 0x124fddb in init__anon_21743 (zstatus)
.certificate => return error.TlsCertificateNotVerified,
^
/home/michael/opt/zig-linux-x86_64-0.14.0-dev.1820+ea527f7a8/lib/std/http/Client.zig:1357:99: 0x118a07f in connectTcp (zstatus)
conn.data.tls_client.* = std.crypto.tls.Client.init(stream, client.ca_bundle, host) catch return error.TlsInitializationFailed;
^
/home/michael/opt/zig-linux-x86_64-0.14.0-dev.1820+ea527f7a8/lib/std/http/Client.zig:1492:14: 0x1153ee0 in connect (zstatus)
} orelse return client.connectTcp(host, port, protocol);
^
/home/michael/opt/zig-linux-x86_64-0.14.0-dev.1820+ea527f7a8/lib/std/http/Client.zig:808:26: 0x1158ab5 in redirect (zstatus)
req.connection = try req.client.connect(new_host, uriPort(valid_uri, protocol), protocol);
^
/home/michael/opt/zig-linux-x86_64-0.14.0-dev.1820+ea527f7a8/lib/std/http/Client.zig:1061:17: 0x1130a66 in wait (zstatus)
try req.redirect(req.uri.resolve_inplace(
^
/home/michael/opt/zig-linux-x86_64-0.14.0-dev.1820+ea527f7a8/lib/std/http/Client.zig:1742:5: 0x112b54b in fetch (zstatus)
try req.wait();
^
/home/michael/projects/zstatus/src/main.zig:22:17: 0x114b376 in main (zstatus)
_ = try std.http.Client.fetch(&client, .{
^
```
`std.http.Client.fetch` with https-URL instead of http-URL works
curl / wget can fetch from http-URL
when i tested with curl / wget i could not see any redirect from http to https for the test url, no tls involved there
### Expected Behavior
I expect zig not to do any tls when i fetch a http-URL
Not sure if any of those directly address you issue. If not, you may want to look at opening an issue on codeberg.
So I ran this through a Debugger, and it is failing on this line: To 1024+ bytes to prevent IE from showing its internal.
It looks like the client is not responding correctly to the TLS handshake.
I tried it with curl as well, and curl also errors:
curl: (60) SSL certificate problem: unable to get local issuer certificate