Skip to content

std.crypto.tls.Client hangs on reading application data #25428

@Southporter

Description

@Southporter

Zig Version

0.16.0-dev.463+f624191f9

Steps to Reproduce and Observed Behavior

This also happens in 0.15.1

  1. Open a tcp connection to an imap server (i.e. imap.gmail.com:993).
  2. Wrap this in a TLS client.
  3. Try to read the server info from the client.

Example main.zig

const std = @import("std");
const repro = @import("repro");

const tls = std.crypto.tls;
const net = std.net;

var read_buf: [tls.Client.min_buffer_len]u8 = undefined;
var write_buf: [tls.Client.min_buffer_len]u8 = undefined;
var client_read_buf: [1024]u8 = undefined;
var client_write_buf: [1024]u8 = undefined;

pub fn main() !void {
    const allocator = std.heap.page_allocator;
    const stream = try net.tcpConnectToHost(allocator, "imap.gmail.com", 993);
    defer stream.close();

    var cipher_reader = stream.reader(&read_buf);
    var cipher_writer = stream.writer(&write_buf);
    var ca_bundle: std.crypto.Certificate.Bundle = .{};
    try ca_bundle.rescan(allocator);
    defer ca_bundle.deinit(allocator);

    var client = try tls.Client.init(cipher_reader.interface(), &cipher_writer.interface, .{
        .host = .{
            .explicit = "imap.gmail.com",
        },
        .ca = .{
            .bundle = ca_bundle,
        },
        .read_buffer = &client_read_buf,
        .write_buffer = &client_write_buf,
    });
    defer client.end() catch {};

    const server_info = try client.reader.takeDelimiterExclusive('\n');
    std.debug.print("Server info: {s}\n", .{server_info});
}

The client will hang waiting for information.

I ran this in lldb and found the issue may be related to readIndirect returning zero for application_data.

.application_data => {

If I apply this patch to the Client, then it starts working. I'm not sure how this change would impact the http client though, as that my be doing other bookkeeping that would interfere here.

          .application_data => {
-             r.end += cleartext.len;
-             return 0;
+            return cleartext.len;
        },

Expected Behavior

TLS cleartext is processed correctly, does not hang, and does not skip application data.

Metadata

Metadata

Assignees

No one assigned

    Labels

    bugObserved behavior contradicts documented or intended behavior

    Type

    No type

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions