1

I'm trying to figure out how can I make a proper TLS connection using Gio. The Gio documentation says you can create a TLS connection just by setting the tls flag on the SocketClient. Below is a Gio networking sample from the gnome wiki. When I set the tls flag, the TLS layer is configured automatically but validating the certificates fails unless I skip the validation.

Do I have to validate certificates myself or is GLib supposed to do the validation? Can somebody provide a full example on how to use TLS in Vala?

var host = "developer.gnome.org";

try {
    // Resolve hostname to IP address
    var resolver = Resolver.get_default ();
    var addresses = resolver.lookup_by_name (host, null);
    var address = addresses.nth_data (0);
    print (@"Resolved $host to $address\n");

    // Connect
    var client = new SocketClient ();
    client.set_tls(true);
    // skips certificate validation
    client.set_tls_validation_flags( 0 );

    var conn = client.connect (new InetSocketAddress (address, 443));
    print (@"Connected to $host\n");

    // Send HTTP GET request
    var message = @"GET / HTTP/1.1\r\nHost: $host\r\n\r\n";
    conn.output_stream.write (message.data);
    print ("Wrote request\n");

    // Receive response
    var response = new DataInputStream (conn.input_stream);
    var status_line = response.read_line (null).strip ();
    print ("Received status line: %s\n", status_line);

} catch (Error e) {
    stderr.printf ("%s\n", e.message);
}

And another thing I want to ask is; when I run the code above I get this output:

Resolved developer.gnome.org to 8.43.85.14
Connected to developer.gnome.org
Wrote request
Received status line: HTTP/1.1 200 OK

But when I try to connect 'developer.mozilla.org', I'm getting the following error:

Resolved developer.mozilla.org to 54.192.235.2
Error performing TLS handshake: A packet with illegal or unsupported version was received.

Can anybody tell me the reason why I am getting this error? (By the way the version of GLib installed on my system is 2.64.6)

semicolon
  • 23
  • 5

2 Answers2

1

What you're doing so far is mostly correct, but you will probably want to do a little bit more to handle potential certificate errors during the TLS handshaking (see below).

Do I have to validate certificates myself or is GLib supposed to do the validation?

Note that SocketClient.set_tls_validation_flags is deprecated. To handle validation errors you can connect to the accept_certificate signal on the TlsClientConnection prior to handshaking:

var client = new SocketClient ();
client.set_tls(true);
client.event.connect ((SocketClientEvent event, SocketConnectable connectable, IOStream? connection) => {
    if (event == SocketClientEvent.TLS_HANDSHAKING) {
        ((TlsClientConnection) connection).accept_certificate.connect ((peer_cert, errors) => {
            // Return true to accept, false to reject
        });
    }
});

The errors are GLib.TlsCertificateFlags, so you'll want to determine which (if any) are acceptable. Ideally if there are any errors you would reject the certificate altogether, but if you want to allow self-signed certificates for example, that is possible this way.

You can simply check against the flags to see which ones are included in the errors:

TlsCertificateFlags[] flags = new TlsCertificateFlags[] {
    TlsCertificateFlags.BAD_IDENTITY,
    TlsCertificateFlags.EXPIRED,
    TlsCertificateFlags.GENERIC_ERROR,
    TlsCertificateFlags.INSECURE,
    TlsCertificateFlags.NOT_ACTIVATED,
    TlsCertificateFlags.REVOKED,
    TlsCertificateFlags.UNKNOWN_CA
};
foreach (var flag in flags) {
    if ((errors & flag) != 0) {
        // The flag was included in the errors - respond accordingly
    }
}

But when I try to connect 'developer.mozilla.org', I'm getting the following error:

Resolved developer.mozilla.org to 54.192.235.2 Error performing TLS handshake: A packet with illegal or unsupported version was received.

Can anybody tell me the reason why I am getting this error? (By the way the version of GLib installed on my system is 2.64.6)

This is probably due to developer.mozilla.org using an old implementation of TLS (probably 1.0 or 1.1). These were disabled in GLib networking as of 2.64.x according to this bug report: https://bugs.debian.org/cgi-bin/bugreport.cgi?bug=954742

They may have upgraded to TLS 1.2 since you posted this question - I just did a quick test and connected using TLSv1.2 successfully.

avojak
  • 2,342
  • 2
  • 26
  • 32
0

Try run the program with export G_MESSAGES_DEBUG=all for full debug messages.

Also, for a full working example of code that uses TLS written in Vala via GIO, check out the code for this Gemini browser: https://github.com/koyuspace/fossil/blob/main/src/util/connection_helper.vala

I hope that this is somewhat useful to you.