How to replace TlsCertificate in runtime

I’m using working example from this subject but when trying to update TlsCertificate for same address by creating new TlsClientConnection with set_certificate in runtime, seems this certificate not applying but yet using previous one. Found also connect_accept_certificate event not emiting twice (on cert change in runtime), only on first handshake / certificate given or application restart.

Can’t find the reason, maybe GTK somewhere cache this handshake for URL?
Reading about TlsDatabase and TlsInteraction, maybe the reason in that

UPD. just created related subject on Rust forum with more details, not sure maybe it’s memory management issue (again as I have another problem before, with reference count for SocketConnection auto-decrease):

It seems that GTK creates some cached Database on server side, and I can’t apply new certificate on app / client side because of that.

For example, memory address to TlsDatabase always same (after first init), even I create new socket and connection, it’s same and maybe takes old Cert for new connection from there:

Some(TlsDatabase { inner: TypedObjectRef { inner: 0x55b52c59a400, type: GTlsDatabaseGnutls } })
Some(TlsDatabase { inner: TypedObjectRef { inner: 0x55b52c59a400, type: GTlsDatabaseGnutls } })

Don’t know how can I drop old database, this option does not work yet

tls_connection.set_database(None::<&gtk::gio::TlsDatabase>);

UPD. TlsDatabase related with TlsBackend where same address in memory. Only this address is same, so reason maybe in that - socket, connection addresses updated but they works with previous database keep old cert so I can’t apply new cert until restart the app (and generate new database) madness!

Why does GTK have anything to do with this? I assure you that GTK doesn’t know anything about TLS and it’s not responsible for whatever TLS server you’re connecting to.

Most likely you’re just encountering session resumption. I don’t think GTlsConnection offers any way to turn off session resumption.

For example, memory address to TlsDatabase always same (after first init), even I create new socket and connection, it’s same and maybe takes old Cert for new connection from there:

The default database is a singleton object.

You can provide your own GTlsDatabase if you want, but it’s not recommended because it removes several security guarantees. Read the documentation carefully if you’re going to do this. g_tls_connection_set_database() has been around for at least a decade, so I don’t know why you say “this option does not work yet.”

1 Like

Most likely from 'gtk::gio' etc in rust code, which looks very weird.

Why does GTK have anything to do with this?

I’m just debugging memory address change and only TlsDatabase permanent for active session.

Most likely you’re just encountering session resumption

Maybe, some session or internal cache. I see no other reasons why after set_certificate new connection created with constructor, work with previous certificate yet.

I’m doing that just because of that’s maybe one reason where connection grab previous cert from. I hope GTlsDatabase related, in session resumption or no (at least only DB memory address same as given by TlsBackend), because if not, will give up find any replacement for socket API able to update cert for new connection.

I don’t know why you say “this option does not work yet.”

I mean None in Rust or NULL in C argument for set_database, it just applies previous GTlsDatabase from TlsBackend not create new one, or disables it.

Btw, not sure about TlsInteraction, there is some request_certificate maybe could drop this session cache.

UPD ChatGPT said I can operate with properties:

tls_connection.set_property("use-session-tickets", false);
tls_connection.set_property("use-session-ids", false);

maybe the answer is really somewhere there

UPD Found TlsFileDatabase class that implement TlsDatabase so database change does not help here.

Pff, seems finally found how to update cert in runtime - it’s just store previous TlsConnection somewhere in memory, then apply handshake to it.

Even have this warning:

Error { domain: g-tls-error-quark, code: 1, message: "Peer does not support safe renegotiation" }

suppose it causes an error in session and forcefully init session reload/cleanup
will find a way to make it properly, at least it work.

I think the misunderstanding is that although you have a new GTlsConnection object, you don’t actually have a new TLS connection. It’s just resuming your previous connection. The API doesn’t allow you to control this. What you’re trying to do is quite unusual, so you might be better off using GnuTLS (or OpenSSL) directly.

Whoever came up with that should reconsider, since GIO is not related to GTK.

Looks like it’s just making stuff up. I’m actually mildly impressed that it was smart enough to realize that session tickets are the problem here and to give you an answer that looks plausible, but I’m afraid those properties are fake. There’s not actually any option to turn off session resumption.

But the documentation warns you not to do that, because this only works if you are using TLS 1.2. So if the server gets upgraded, now your code will break.

1 Like

it should be new, at least I expect that from new SocketClient, new TlsCertificate, new NetworkAddress and new SocketConnection in reload action call.

Whoever came up with that should reconsider, since GIO is not related to GTK.

maybe question to gtk-rs devs, no idea why does it have this namespace

But the documentation warns you not to do that, because this only works if you are using TLS 1.2. So if the server gets upgraded, now your code will break.

Thanks, saw these lines, at least found something makes react to updates, of course that is not final solution

That’s a side effect of Rust imports, just like including gtk/gtk.h in your C application automatically includes gio/gio.h: without it, you would not be able to use GTK types that inherit from GIO types, like GtkApplication.

Of course, you have to know that GIO is separate and has nothing to do with GTK if you’re using the GNOME platform, regardless of the programming language you’re using.

It’s a new object, sure, but session tickets are cached for the entire process. You would need to create a new Unix process if you want a truly new connection. You can look at the documentation of g_tls_client_connection_copy_session_state() for more details. It’s not documented more prominently because it usually doesn’t matter; it’s quite unusual that you’re trying to switch client certificates, which is one of the few situations in which this would be a problem. See also: gtlssessioncache.c

1 Like

Another devs yet trying to build their wrappers with reverse namespace. I’ve tried make contribution to PHP-GTK3, by defining glib instead of gtk for some new class implementation, but maintainer prefer gtk for g_markup_escape_text

I’m beginner anyway, to have participate this discussion.

gtk::gio is just a redeclaration, so you can import one module and get all the bits you need. If you’re not using GTK, you can import gio directly: gio - Rust

1 Like

it’s quite unusual that you’re trying to switch client certificates

I’m trying to implement certificate change for Gemini protocol (browser), here is specification, if interesting what I’m doing:
https://geminiprotocol.net/docs/protocol-specification.gmi#client-certificates

So user able to change identity (or user certificate) to communicate with server as registered member. User also may want to change this identity (certificate) in runtime, when want to re-login. There is no login/passwords, like in web, but certificates instead.

Seems my current implementation absolutely incorrect, and I should rewrite it according to multi-session / multi-tab implementation, like you advice. Thanks much for corrections. I’m always stuck with something when doing it wrong.

Just tried do some trick by store previous TlsClientConnection and apply copy_session_state to it from new TlsClientConnection that contain new TlsCertificate - no luck, it fails with error:

GLib-Net-CRITICAL **: 16:11:16.681: g_tls_client_connection_gnutls_copy_session_state: assertion '!gnutls->session_id' failed

Is any hope to have session options API in future Gio releases?

I found this option in other TLS libraries, so not alone with this feature request, just want to use Glib environment in GTK app, but normally can’t make it working without warnings for TLS 1.3 version. Everything I can do now - it’s only session reindex by it crash on rehandshake failure…

I think you’re trying to call g_tls_client_connection_copy_session_state() on a GTlsClientConnection that has already handshaked. But the documentation says you’re not allowed to do that.

(That said, I’m pretty sure that moving your TLS session from one GTlsClientConnection object to another is not actually going to help you, even if you do get it working.)

Sort of. It’s open source, and merge requests are welcome. But there are not many contributors, so it’s unlikely that somebody else will develop it for you. Sorry.

Finally found solution by reading this code.

At least 2 properties, for some reasons, not documented yet:

g_object_class_override_property (gobject_class, PROP_SESSION_REUSED, "session-reused");
g_object_class_override_property (gobject_class, PROP_SESSION_RESUMPTION_ENABLED, "session-resumption-enabled");

by setting:

tls_client_connection.set_property("session-resumption-enabled", false);

on new TlsClientConnection create, it will no longer reuse old session.

Now application able to change certificate in runtime without deprecated re-handshake call. And I can see this update applying on accept_certificate event.

Entire client library implementation here.

Those aren’t APIs, though. They’re implementation details which could go away tomorrow. It might make sense to expose them as APIs, though.

1 Like

Please keep this option,

more of that, I think that session resumption should be disabled by default as may produce security risks and/or confuse by cache old certificate when new one given without any warning.

It’s not a security risk and it’s important for performance. I’m not going to turn off session resumption. My recommendation for you is to investigate some more and try to figure out what is wrong.